let a = [];
a.push(0);

  1. noImplicitAnystrictNullChecks都设置为true
  2. noImplicitAnystrictNullChecks都设置为false

但当

  1. noImplicitAny为假,strictNullChecks为真

发出的错误为Argument of type 'number' is not assignable to parameter of type 'never'.

似乎在前两种情况下,a被推断为any[],而在最后一种情况下,a被推断为never[],但为什么会发生这种情况?

请判断下面所附的图像以了解所使用的错误和选项.

First two cases: enter image description here

Last case: enter image description here

推荐答案

这个问题是在microsoft/TypeScript#36987年提出的.权威(但不是特别有用)的答案是,这种行为符合预期,并且是向后兼容性所必需的.一般来说,TypeScript不会引入突破性的更改,除非这些更改改进了比突破更多的东西.


the --noImplicitAny compiler optionthe --strictNullChecks compiler option都启用时,空数组实际上不是any[]类型;相反,它们是"自动"或"通配符"或"进化"类型,根据观察到要添加到其中的值而变化.这在microsoft/TypeScript#11432中实施:

let a = []; // auto-typed
a.push(0); // now a is seen as number[]
a.map(x => x.toFixed()) // okay
a.map(x => x.toUpperCase()) // error, numbers don't have a toUpperCase() method

--noImplicitAny为off时,不会发生这种情况,因为这样做会给以前"良好"的现有代码添加新的错误(如果aany[]类型的,那么map()方法中的x应该是any类型的,因此x.toUpperCase()x.toFaxed()或任何东西上都不会发生错误).


至于--strictNullChecks的开启与关闭之间的区别,有几个bug修复与空数组文本与其他用例的严重交互有关;参见microsoft/TypeScript#19576microsoft/TypeScript#19745.这些修复程序在--strictNullChecks打开时更改了行为,但在关闭时没有更改,以便在这些其他用例中保持向后兼容性.


所以这就是发生的事情,或多或少.您看到了在某些编译器选项面前,几个特性和bug修复以一种特殊的方式相互作用的后果.

从实用主义的Angular 来说,你应该尽可能地使用--strict suite of compiler options.这为您提供了"标准"的类型安全性,并且被广泛使用,因此社区中有大量的文档和讨论.如果您有 Select 地禁用某些编译器选项,并且遇到一些奇怪或意外的情况,那么您可用的资源就会减少,因为您可能是拥有这种配置的极少数人之一.即使你发现了一个真正的语言错误,修复它的压力也会减小,所以它可能会持续很长时间或永远.

Playground link to code

Typescript相关问答推荐

在泛型类型中对子代执行递归时出错

迁移到Reaction路由V6时,获取模块Reaction-Router-Dom';没有导出的成员RouteComponentProps错误

隐式键入脚本键映射使用

React重定向参数

TypeScrip表示该类型不可赋值

使用TypeScrip根据(可选)属性推断结果类型

在类型脚本中的泛型类上扩展的可选参数

对未到达受保护路由的路由环境做出react

在另一个类型的函数中,编译器不会推断模板文字类型

迭代通过具有泛型值的映射类型记录

如何 bootstrap TS编译器为类型化属性`T`推断正确的类型?

我不明白使用打字脚本在模板中展开参考

在构建Angular 应用程序时,有没有办法通过CLI传递参数?

使用Cypress测试从Reaction受控列表中删除项目

两个名称不同的相同打字界面-如何使其干燥/避免重复?

TypeScript是否不知道其他函数内部的类型判断?

如何使用 AWS CDK 扩展默认 ALB 控制器策略?

如何强制对象数组中的对象属性具有非空字符串值?

如何解决 Angular 中的 ts(18048) 错误

如何在react-router-dom v6中捕获pop事件