为什么 TypeScript 流程分析不覆盖 else 块?

hop*_*mer 2 types static-analysis typescript

让我们考虑以下代码:

function f(x : number) {
    if (x === 1) {
        if (x === 2) {} // error
    }
    else {
        if (x === 1) {} // OK
    }
}
Run Code Online (Sandbox Code Playgroud)

在这里,编译器给了我一个错误x === 2。原因很简单:如果执行已经到达此块,则x应该1通过x === 1。由于12没有重叠,因此不可能x同时是12

但编译器完全可以x === 1接受else. 这应该是不可能的,因为语句中的x检查已经失败。由于不能满足两者,第二个应该给我与 相同的错误。x === 1ifxx === 1!(x === 1)ifx === 2

这怎么可能?这是高级流量分析的某种未实现的功能吗?这是一个错误吗?又或许这个案例有一些隐藏的逻辑,最终还是有一定道理的?

谢谢。

Ale*_*yne 5

因为 Typescript 无法表达类型,例如number不是特定数字。

当你这样做时:

if (x === 1) { x } // x is type: 1
Run Code Online (Sandbox Code Playgroud)

然后它就知道x1那个区块中。这很好,1是有效且有用的类型。静态地说这1 === 2永远不会是真的,这是微不足道的。

但在 else 块中:

if (x === 1) { x }
else { x } // x is type: number
Run Code Online (Sandbox Code Playgroud)

然后x是 type number,因为类型系统无法表达“除1”之外的所有数字。因此,编译器实际上不能保证代码路径不能被采用,即使您可以看到这一点。


当然,这是类型系统的限制。但 Typescript 并不完美。它是一种建立在不同语言之上的类型系统,这是您必须满足的事情之一。