When the array is empty, TS does no type checking
My code here
type List = { name: string }[]
const l: List = []
// error
l[0].name
Is there any way to make TS check?How do I make TS check work?
CodePudding user response:
Enable noUncheckedIndexedAccess
in compilerOptions
in your tsconfig.json
.
After this you will start getting TS errors like Object is possibly 'undefined'.(2532)
on such statements.
type List = { name: string }[]
const l: List = []
l[0].name // <-- error
l[0]?.name // <-- no error (ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining)
Note that noUncheckedIndexedAccess
option doesn't check the length of your array; it basically keeps reminding you that the index you are trying to access may not exist.
If your array (and its elements) are meant to be read only, you can also use const assertion:
const l = [{ name: 'foo' }] as const
l[0].name // no error
l[1] // error: Tuple type 'readonly [{ name: 'foo'; }]' of length '1' has no element at index '1'.(2493)
If you just want your array length to be fixed but the elements mutable, then in TS4.1 and above you can do this:
// based on - https://stackoverflow.com/a/52490977
type _TupleOf<T, N extends number, R extends unknown[]> = R['length'] extends N ? Readonly<R> : _TupleOf<T, N, [T, ...R]>
type Tuple<T, N extends number> = N extends N ? (number extends N ? T[] : _TupleOf<T, N, []>) : never
type List = Tuple<{ name: string }, 1>
const l: List = [{ name: 'foo' }]
l[0].name // no error
l[1] // error: Tuple type 'readonly [{ name: string; }]' of length '1' has no element at index '1'.(2493)