简体   繁体   English

Typescript:访问数组元素不考虑未定义返回值的可能性

[英]Typescript: accessing an array element does not account for the possibility of undefined return values

The following passes the Typescript type checker (v2.9.1), but throws a TypeError at run time.以下代码通过了 Typescript 类型检查器 (v2.9.1),但在运行时抛出TypeError

interface Item { id: string }
const list: Item[] = [{ id: 'a' }, { id: 'b' }];
const item = list[3]; // type: Item
const itemId = item.id; // type: string

Given that accessing an element in a typed array could always return undefined , shouldn't item be item: Item | undefined鉴于访问类型化数组中的元素总是会返回undefined ,所以 item 不应该是item: Item | undefined item: Item | undefined , which would force you to do a null check? item: Item | undefined ,这会迫使您进行 null 检查?

Even more surprisingly to me, the following also type checks:更令我惊讶的是,以下还进行了类型检查:

const item2: Item | undefined = list[3];
const item2Id = item2.id;

though casting the returned value does successfully fail the type check:尽管转换返回值确实成功地使类型检查失败:

const item3 = list[3] as Item | undefined;
const item3Id = item3.id; // [ts] Object is possibly 'undefined'.

Creating an explicitly typed accessor function also catches the undefined case, but adds unnecessary overhead:创建显式类型的访问器 function 也捕获未定义的情况,但增加了不必要的开销:

const getItem1 = (index: number, items: Item[]): Item | undefined => items[index];
const item3 = getItem1(3, list);
const item3Id = item3 && item3.id;

Is this a known limitation of typescript?这是 typescript 的已知限制吗? Are there recommended patterns or libraries for handling this case?是否有推荐的模式或库来处理这种情况?

PRE-TS4.1 ANSWER: TS4.1 之前的答案:

You have discovered that index signatures don't add | undefined您发现索引签名不添加| undefined | undefined to the element type the way that optional properties do. | undefined元素类型的方式与可选属性一样。 It has been suggested at microsoft/TypeScript#13778 to create a compiler option that would do this.已在microsoft/TypeScript#13778 中建议创建一个编译器选项来执行此操作。 You can read the comments in that suggestion;您可以阅读该建议中的评论; they link to other issues, but the consensus is that the high false positive rate would make it nearly useless.它们与其他问题有关,但一致认为高误报率将使其几乎无用。

It is also mentioned that you have the ability to manually add | undefined还提到您可以手动添加| undefined | undefined to the element type: | undefined到元素类型:

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

which will behave as you expect, without affecting the whole language.它将按照您的预期运行,而不会影响整个语言。


UPDATE for TS 4.1: TS 4.1 更新:

TypeScript 4.1 introduced a --noUncheckedIndexedAccess compiler flag that implements the suggestion in microsoft/TypeScript#13778 to account for undefined in this way. TypeScript 4.1 引入了一个--noUncheckedIndexedAccess编译器标志,它实现了microsoft/TypeScript#13778 中的建议,以这种方式解释undefined Note that the feature will not be enabled as part of the --strict set of compiler options and is being called "pedantic index signatures" because it will end up complaining about the possibility of undefined in situations where programmers might not expect or desire it.请注意,该功能不会作为--strict编译器选项集的一部分启用,而是被称为“迂腐索引签名”,因为它最终会抱怨在程序员可能不期望或不希望它的情况下undefined的可能性。

This is the intentional behavior.这是故意行为。 See this issue on the TypeScript GitHub repo for a long discussion请参阅 TypeScript GitHub 存储库上的此问题进行长时间讨论

Even more surprisingly to me, the following also type checks:更令我惊讶的是,以下还进行了类型检查:

You have strictNullChecks off;您关闭了strictNullChecks try turning it on.尝试打开它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM