这个问题是在microsoft/TypeScript#36987年提出的.权威(但不是特别有用)的答案是,这种行为符合预期,并且是向后兼容性所必需的.一般来说,TypeScript不会引入突破性的更改,除非这些更改改进了比突破更多的东西.
当the --noImplicitAny
compiler option和the --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时,不会发生这种情况,因为这样做会给以前"良好"的现有代码添加新的错误(如果a
是any[]
类型的,那么map()
方法中的x
应该是any
类型的,因此x.toUpperCase()
或x.toFaxed()
或任何东西上都不会发生错误).
至于--strictNullChecks
的开启与关闭之间的区别,有几个bug修复与空数组文本与其他用例的严重交互有关;参见microsoft/TypeScript#19576和microsoft/TypeScript#19745.这些修复程序在--strictNullChecks
打开时更改了行为,但在关闭时没有更改,以便在这些其他用例中保持向后兼容性.
所以这就是发生的事情,或多或少.您看到了在某些编译器选项面前,几个特性和bug修复以一种特殊的方式相互作用的后果.
从实用主义的Angular 来说,你应该尽可能地使用--strict
suite of compiler options.这为您提供了"标准"的类型安全性,并且被广泛使用,因此社区中有大量的文档和讨论.如果您有 Select 地禁用某些编译器选项,并且遇到一些奇怪或意外的情况,那么您可用的资源就会减少,因为您可能是拥有这种配置的极少数人之一.即使你发现了一个真正的语言错误,修复它的压力也会减小,所以它可能会持续很长时间或永远.
Playground link to code