Phương pháp tiếp cận Tuple:
Giải pháp này cung cấp chữ ký loại FixedLengthArray (ak.a. SealedArray) nghiêm ngặt dựa trên Tuples.
Ví dụ về cú pháp:
// Array containing 3 strings
let foo : FixedLengthArray<[string, string, string]>
Đây là cách tiếp cận an toàn nhất, xem xét nó ngăn chặn việc truy cập các chỉ mục ra ngoài ranh giới .
Thực hiện :
type ArrayLengthMutationKeys = 'splice' | 'push' | 'pop' | 'shift' | 'unshift' | number
type ArrayItems<T extends Array<any>> = T extends Array<infer TItems> ? TItems : never
type FixedLengthArray<T extends any[]> =
Pick<T, Exclude<keyof T, ArrayLengthMutationKeys>>
& { [Symbol.iterator]: () => IterableIterator< ArrayItems<T> > }
Kiểm tra:
var myFixedLengthArray: FixedLengthArray< [string, string, string]>
// Array declaration tests
myFixedLengthArray = [ 'a', 'b', 'c' ] // ✅ OK
myFixedLengthArray = [ 'a', 'b', 123 ] // ✅ TYPE ERROR
myFixedLengthArray = [ 'a' ] // ✅ LENGTH ERROR
myFixedLengthArray = [ 'a', 'b' ] // ✅ LENGTH ERROR
// Index assignment tests
myFixedLengthArray[1] = 'foo' // ✅ OK
myFixedLengthArray[1000] = 'foo' // ✅ INVALID INDEX ERROR
// Methods that mutate array length
myFixedLengthArray.push('foo') // ✅ MISSING METHOD ERROR
myFixedLengthArray.pop() // ✅ MISSING METHOD ERROR
// Direct length manipulation
myFixedLengthArray.length = 123 // ✅ READ-ONLY ERROR
// Destructuring
var [ a ] = myFixedLengthArray // ✅ OK
var [ a, b ] = myFixedLengthArray // ✅ OK
var [ a, b, c ] = myFixedLengthArray // ✅ OK
var [ a, b, c, d ] = myFixedLengthArray // ✅ INVALID INDEX ERROR
(*) Giải pháp này đòi hỏi các noImplicitAny
nguyên cảo bật chỉ thị cấu hình để hoạt động (phương pháp thường được khuyến nghị)
Cách tiếp cận Mảng (ish):
Giải pháp này hoạt động như một phần tăng thêm của Array
kiểu, chấp nhận một tham số thứ hai bổ sung (Độ dài mảng). Không nghiêm ngặt và an toàn như giải pháp dựa trên Tuple .
Ví dụ về cú pháp:
let foo: FixedLengthArray<string, 3>
Hãy nhớ rằng cách tiếp cận này sẽ không ngăn bạn truy cập một chỉ mục ngoài ranh giới đã khai báo và đặt giá trị trên đó.
Thực hiện :
type ArrayLengthMutationKeys = 'splice' | 'push' | 'pop' | 'shift' | 'unshift'
type FixedLengthArray<T, L extends number, TObj = [T, ...Array<T>]> =
Pick<TObj, Exclude<keyof TObj, ArrayLengthMutationKeys>>
& {
readonly length: L
[ I : number ] : T
[Symbol.iterator]: () => IterableIterator<T>
}
Kiểm tra:
var myFixedLengthArray: FixedLengthArray<string,3>
// Array declaration tests
myFixedLengthArray = [ 'a', 'b', 'c' ] // ✅ OK
myFixedLengthArray = [ 'a', 'b', 123 ] // ✅ TYPE ERROR
myFixedLengthArray = [ 'a' ] // ✅ LENGTH ERROR
myFixedLengthArray = [ 'a', 'b' ] // ✅ LENGTH ERROR
// Index assignment tests
myFixedLengthArray[1] = 'foo' // ✅ OK
myFixedLengthArray[1000] = 'foo' // ❌ SHOULD FAIL
// Methods that mutate array length
myFixedLengthArray.push('foo') // ✅ MISSING METHOD ERROR
myFixedLengthArray.pop() // ✅ MISSING METHOD ERROR
// Direct length manipulation
myFixedLengthArray.length = 123 // ✅ READ-ONLY ERROR
// Destructuring
var [ a ] = myFixedLengthArray // ✅ OK
var [ a, b ] = myFixedLengthArray // ✅ OK
var [ a, b, c ] = myFixedLengthArray // ✅ OK
var [ a, b, c, d ] = myFixedLengthArray // ❌ SHOULD FAIL
arr
sau khi nó được khởi tạo.