4 ms·
For this code: const x = [1,2]; const y = x[666]; const z = y + 3; Is there a way for TypeScript to flag the last line as a type error? TypeScrip
by seanwilson 7y ago
For this code:
const x = [1,2];
const y = x[666];
const z = y + 3;
Is there a way for TypeScript to flag the last line as a type error?
TypeScript will say "y" has type "number" when "x[666]" returns undefined. Why does TypeScript not say the type of "y" is "number | undefined"?
- Eyas 7y agoNot really https://github.com/microsoft/TypeScript/issues/9235 https://github.com/microsoft/TypeScript/issues/9235 Though with tuples, etc. being defined, maybe it's worth re-examining.
- seanwilson 7y agoThanks. Is there a pattern for array access that helps with my example? Is the only option to define your own safe access function like "function safeGetFromArray<T>(array: T, index:number): T | undefined"? I haven't tried it yet but it looks like the new optional element access feature is only checking if the array itself is defined, not if the array index is defined.
- emptysea 7y agoI can't seem the find the GitHub issue for it off hand, but I believe you can override the default indexing signature for arrays to return possibly undefined. Otherwise, you're left to creating a wrapper function and a custom ESlint rule. Edit: found it https://github.com/microsoft/TypeScript/issues/13778#issuecomment-277029664 https://github.com/microsoft/TypeScript/issues/13778#issueco... The suggestion is to maintain your own copy of `index.d.ts` with the array indexing interface modified. Yikes!
- jakelazaroff 7y agoFor array types, I don't think there's a way. You can type x as a tuple like this: const x: [number, number] = [1, 2]; In which case you'll only be able to access indices zero and one.
- scottlecrab 7y agohttps://www.typescriptlang.org/play/index.html#code/MYewdgzgLgBAHjAvDA2gRgDQCYC6MCGEMokUA3AFAnQwCeS8KAbCzpdbAF4P0DUMAZjJA https://www.typescriptlang.org/play/index.html#code/MYewdgzg... Using `as const` will report both the 2nd and 3rd lines as type errors. You've been able to do this in TypeScript for a while even before they introduced the `as const` syntax.
- seanwilson 7y agoThanks, you can still trick it with this though (there's no type error): const x = [1, 2] as const; const r = 666 + 1; const y = x[r]; const z = y + 3;
- nine_k 7y agoLet's wait until TS supports dependent types!
- _s 7y agoPerhaps explicitly setting the types might do it? const x: number[]= [1,2] const y: number | undefined = x[666] const z: number = y + 3 EDIT: Just tried, still works
- ht85 7y agoIt works because `undefined + number -> NaN`, and NaN is a number.
- tmkn13 7y agoYes there is, you can either use as const or define the type as a tuple: const x = [1,2] as const; //const x: [number, number] = [1,2]; const y = x[666];//Tuple type 'readonly [1, 2]' of length '2' has no element at index '666'. const z = y + 3;//Object is possibly 'undefined'. Both versions will error the same.