为什么 Typescript 会推断由没有未定义的缺失键检索到的值的类型?

Why does Typescript infer type of a value retrieved by absent key without undefined?

我有这个示例代码:

const example: { [key: string]: string } = { a: 'abc' }

const b = example['b']

在运行时,b 显然等于 undefined,但在编译类型中,Typescript 推断 b 类型只是 string 而不是 string|undefined.这对我来说似乎是个错误。

为什么它不将其推断为 string|undefined,我如何强制它这样做?

这不是错误。考虑只输入:'b' 可能是一个有效的键。

类型 { [key: string]: string } 明确地告诉 Typescript example 可以包含任何键名。

Typescript 不会分析 您的变量。它只比较类型并查看它们是否匹配。


在下面的example打字稿中显示错误。因为你列出了可以存在或不存在的键。

type keys = 'a' | 'foo';

const example: { [key in keys]?: string } = { a: 'abc' }

const b = example['b']

您正在将示例转换为 { [key: string]: string } 类型。换句话说,你告诉打字稿它总是一个字符串。打字稿无法分析它是否真的存在,因为它是一种静态类型的语言。

您通过将类型转换为 {[key: string]: string} 来扩展类型,因此从类型的角度来看,'b''a' 一样有效。省略类型并让 typescript 推断更窄的类型,将抛出错误:

const example = { a: 'abc' };

// error: property 'b' does not exist
const b = example['b'];

有关于在 GitHub issue #9235, and it was actually resolved with a noUncheckedIndexedAccess flag added in typescript 4.1 上将 | undefined 添加到索引查找的讨论。如果已设置,那么 b 将是 string | undefined,即使在您的示例中也是如此。

Playground link.