TypeScript 空检查不注意 array.length 检查

TypeScript null checks not paying attention to array.length check

使用严格空值检查编译 TypeScript 时,以下内容即使没问题也不会进行类型检查:

const arr: number[] = [1, 2, 3]
const f = (n: number) => { }
while (arr.length) {
    f(arr.pop())
}

编译错误为:

Argument of type 'number | undefined' is not assignable to parameter of type 'number'. Type 'undefined' is not assignable to type 'number'.

编译器似乎不够聪明,无法知道 arr.pop() 肯定会 return 一个数字。

一些问题:

  1. 为什么编译器不更聪明?为这种情况添加更智能的空值检查会非常困难,还是 TS 团队尚未实施的简单明了的事情?
  2. 编写上面仍然进行类型检查的最惯用的方法是什么?

关于 2,我能想到的最好办法是在循环体中添加一个多余的检查:

while (arr.length) {
    const num = arr.pop()
    if (num) { // make the compiler happy
        f(num)
    }
}

是的,将这种智能添加到编译器被认为是困难的,请参阅 this comment 描述您的问题的确切问题。

与此同时,您可以使用 non-null assertion - 后缀 ! - 告诉编译器您知道该值不为空:

const arr: number[] = [1, 2, 3]
const f = (n: number) => { }
while (arr.length) {
    f(arr.pop()!)
}