我的问题很简单。鉴于此代码:
const array = [1, 2, 3, 4, 5];
const map01 = array.map((v) => v % 2 ? "" : "");
// ^? string[]
const map02 = array.map((v) => v % 2 ? "odd" : "even");
// ^? ("odd" | "even")[]
const map03 = array.map((v) => v % 2 ? "!" : "");
// ^? ("" | "!")[]
Run Code Online (Sandbox Code Playgroud)
为什么 TypeScript 会做出如此奇怪的推论?不应该map01被推断为""[]?
jca*_*alz 10
有关文字类型加宽如何以及何时发生的详细信息,请参阅microsoft/TypeScript#10676。它特别指出:
- 在没有返回类型注释的函数中,如果推断的返回类型是文字类型(但不是文字联合类型),并且该函数没有返回类型包含文字类型的上下文类型,则返回类型将扩展为它的扩展文字类型。
因此,这意味着在 的情况下"odd" | "even",您有一个未加宽的文字联合类型,而在 的情况下,您有一个已""加宽的非联合文字类型。
至于为什么使用这条规则而不是更简单的“从不扩大”规则,这是一个启发式的选择,旨在最大限度地减少“正常”情况下的意外。文字类型通常在联合中比单独使用更有用,因此编译器假设function foo() {return "abc"}更有可能返回string,而function bar() {return Math.random<0.5 ? "abc" : "def"}更有可能返回文字的联合。作为一种启发式方法,它并不完美,但它显然比其他方法引起的惊喜要少。
GitHub 中存在各种问题,当前行为被视为按预期工作;例如,请参阅带有以下评论的microsoft/TypeScript#51551:
扩大规则是为了启发式地尝试推断“更好”的类型,并且允许不同的代码在这些启发式下有不同的行为
| 归档时间: |
|
| 查看次数: |
144 次 |
| 最近记录: |