Hacker News new | past | comments | ask | show | jobs | submit login

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"?




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.


Thanks, 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;


Let's wait until TS supports dependent types!


Yes 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.


For 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.


Not really https://github.com/microsoft/TypeScript/issues/9235

Though with tuples, etc. being defined, maybe it's worth re-examining.


Thanks. 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.


I 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#issueco...

The suggestion is to maintain your own copy of `index.d.ts` with the array indexing interface modified. Yikes!


Perhaps 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


It works because `undefined + number -> NaN`, and NaN is a number.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: