Typescript code that does not take into account the possibility of array elements returning undefined
P粉824889650
P粉824889650 2023-08-24 12:15:44
0
2
654
<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粉824889650
P粉824889650

reply all(2)
P粉194541072

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

Your strictNullChecks is off; try turning it on.

P粉330232096

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.

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template