Home  >  Q&A  >  body text

Typescript code that does not take into account the possibility of array elements returning undefined

<p>The following code passes in the Typescript type checker (v2.9.1), but throws <code>TypeError</code> at runtime. </p> <pre class="brush:php;toolbar:false;">interface Item { id: string } const list: Item[] = [{ id: 'a' }, { id: 'b' }]; const item = list[3]; // Type: Item const itemId = item.id; // Type: string</pre> <p>Considering that accessing an element in a typed array may always return <code>undefined</code>, <code>item</code> should be <code>item: Item | undefined</code> , which would force you to do a null check, shouldn't it? </p> <p>What surprised me even more is that the following code also passed the type check: </p> <pre class="brush:php;toolbar:false;">const item2: Item | undefined = list[3]; const item2Id = item2.id;</pre> <p>Although casting the return value does cause the type check to fail: </p> <pre class="brush:php;toolbar:false;">const item3 = list[3] as Item | undefined; const item3Id = item3.id; // [ts] Object is possibly 'undefined'.</pre> <p>Creating an explicitly typed accessor function can also capture the <code>undefined</code> situation, but it will add unnecessary overhead: </p> <pre class="brush:php;toolbar:false;">const getItem1 = (index: number, items: Item[]): Item | undefined => items[index]; const item3 = getItem1(3, list); const item3Id = item3 && item3.id;</pre> <p>Is this a known limitation of Typescript? Is there any recommended pattern or library to handle this situation? </p>
P粉824889650P粉824889650423 days ago604

reply all(2)I'll reply

  • P粉194541072

    P粉1945410722023-08-25 11:31:36

    This is intentional behavior. View the long discussion on this issue on the TypeScript GitHub repository

    Your strictNullChecks is off; try turning it on.

    reply
    0
  • P粉330232096

    P粉3302320962023-08-25 11:19:47

    TS 4.1 Update:

    TypeScript 4.1 introduced a --noUncheckedIndexedAccess compiler flag that implements the suggestion made in microsoft/TypeScript#13778 to account for this case undefined. Note that this feature is not enabled as part of the --strict compilation option set, and is referred to as a "strict index signature" because it emits situations where the programmer may not want or expect Warning about undefined.


    TS4.1 previous answer:

    You've discovered that index signatures do not add | undefined to element types like optional properties do. The suggestion to create a compiler option to achieve this was made at microsoft/TypeScript#13778. You can read the comments in that suggestion; they link to other questions, but the consensus is that the high error rate almost makes it useless.

    also mentioned that you can manually add | undefined to the element type:

    const list: (Item | undefined)[] = [{ id: 'a' }, { id: 'b' }];

    This will work as you expect without affecting the entire language.

    reply
    0
  • Cancelreply