问题描述
以下通过 Typescript 类型检查器 (v2.9.1),但在运行时抛出 TypeError
.
The following passes the Typescript type checker (v2.9.1), but throws a TypeError
at run time.
interface Item { id: string }
const list: Item[] = [{ id: 'a' }, { id: 'b' }];
const item = list[3]; // type: Item
const itemId = item.id; // type: string
鉴于访问类型化数组中的元素可能总是返回undefined
,item 不应该是item: Item |未定义
,这会强制你做空检查?
Given that accessing an element in a typed array could always return undefined
, shouldn't item be item: Item | undefined
, which would force you to do a null check?
更令我惊讶的是,以下内容也进行了类型检查:
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:
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? Are there recommended patterns or libraries for handling this case?
推荐答案
PRE-TS4.1 ANSWER:
您发现索引签名不添加|undefined
以可选属性的方式添加到元素类型.建议创建一个编译器选项来执行此操作.您可以阅读该建议中的评论;它们与其他问题相关联,但一致认为高误报率会使它几乎无用.
PRE-TS4.1 ANSWER:
You have discovered that index signatures don't add | undefined
to the element type the way that optional properties do. It has been suggested to create a compiler option that would do this. 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
to the element type:
const list: (Item | undefined)[] = [{ id: 'a' }, { id: 'b' }];
这将按照您的预期运行,而不会影响整个语言.
which will behave as you expect, without affecting the whole language.
TypeScript 4.1 引入了 --noUncheckedIndexedAccess
编译器标志,它实现了 microsoft/TypeScript#13778 以这种方式解释 undefined
.请注意,该功能将不会作为 --strict
编译器选项集的一部分启用,而是被称为迂腐索引签名".因为它最终会在程序员可能不期望或不希望它的情况下抱怨 undefined
的可能性.
TypeScript 4.1 introduced a --noUncheckedIndexedAccess
compiler flag that implements the suggestion in microsoft/TypeScript#13778 to account for undefined
in this way. 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.
这篇关于打字稿:访问数组元素不考虑未定义返回值的可能性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!