带有严格的空检查的打字稿 - 数组访问呢?



在打字稿中,如果启用了严格的null检查,我希望编译器可以防止我将nullundefined值分配给变量,除非它允许null

但是,数组访问似乎允许绕过此支票。

示例:

let a: string[] = ["Hello"];
let s: string;
// 1) this produces an error, as expected
s = undefined
// 2) s is undefined here, too, but no error
s = a[3];
console.log(s);

打字稿操场上的可运行版本(请注意:"严格的null检查"必须在"选项"对话框中启用)。

这里发生了什么?

  • 这是打字稿编译器中的错误吗?
  • 还是故意的遗漏?
  • 如果后者是任何地方记录的(理想情况下,为什么要这样做)?

找到了它: - )。

tl; dr:这是故意的遗漏。在打字稿代码中,数组访问非常常见,并且强迫每次访问的空/未定义检查对于开发人员来说太麻烦了。

请注意,由于Typescript 4.1这是可以使用编译器选项noUncheckedIndexedAccess配置的。有关详细信息,请参见Klaster_1的答案。


该问题在讨论中已多次提出:

  • 问题#11122-数组查找应返回t |未定义
  • 对PR 7140的评论
  • #6229-建议:严格和开放的元组类型

对PR 7140的评论有Anders Hejlsberg(核心开发人员之一)的不错的理由:

索引简单地产生匹配中声明的类型的值索引签名。即使在技术上更正确,它也会如果我们自动将undefined添加到类型每个索引操作。

例如,每个数组元素访问必须伴随着非无效的后卫或!断言。我认为这会变得非常烦人。


个人评论:我认为这是一个合理的决定。问题是数组固有的 - 我认为是否可以(对于编译器)证明是否定义给定位置,因为您可以使用计算的位置。因此,任何警告都会产生许多误报,大多数开发人员无论如何都会关闭它。

本质上,阵列为开发人员提供了比编译器可以检查的更多自由。如果您需要进行适当的检查,我可以看到的唯一解决方案是避免直接访问阵列,并使用其他提供更多保护的数据结构。

typescript 4.1引入了一个新的编译器选项-NOUNCHECKECKEDINDEXEDACCESS。除其他外,它将undefined添加到数组索引访问类型。

考虑以下片段(TS游乐场):

const items = [1,2,3]
console.log(items[1]?.toString(10))
console.log(items[2].toString(10))

没有noUncheckedIndexedAccessitems[2].toString(10)将被视为有效,并且在选项打开时无效。该选项打开时,items[1]?.toString(10)将有效,就像Alex Neth在旧答案中的评论一样。

相关内容

  • 没有找到相关文章

最新更新