为什么非空断言运算符 (!) 不会向结果 JS 发出实际的非空和非未定义检查

Mak*_*sym 2 null undefined typescript

当使用非空断言运算符时,Typescript 编译器向结果 JS 发出非未定义和非空检查似乎是合理的。IE,:

function fun1(node: SomeType | undefined) {
    fun2(node!);
}
Run Code Online (Sandbox Code Playgroud)

应该转换为:

function fun1(node) {
    if (node === undefined || node === null) {
        throw new Error('The non-null assertion failed!');
    }
    fun2(node);
}
Run Code Online (Sandbox Code Playgroud)

然而,正如文档所说的那样,它只会被转译为:

function fun1(node) {
    fun2(node);
}
Run Code Online (Sandbox Code Playgroud)

为什么呢?不将检查添加到输出 JS 代码背后的原因是什么?

Eri*_*rik 5

非空断言运算符的重点是告诉 TypeScript 编译器您已经知道该变量不为空。考虑以下场景:

function fun1(node: SomeType | undefined) {
    throwIfUndefined(node);
    node!.fun2();
}
Run Code Online (Sandbox Code Playgroud)

您调用一个函数,如果node未定义,该函数将引发异常。因此,实际上没有必要在调用之前检查 node 是否未定义fun2。但是,TypeScript 编译器无法推断出这一点,因此如果没有感叹号,它将拒绝编译您的代码,因为它认为您没有处理空情况。但是,如果您作为程序员知道这种情况永远不会发生,为什么要在最终产品中插入一个会消耗 CPU 周期的冗余检查呢?非空断言运算符实际上只是告诉编译器的一种方式,“是的,我知道你不能说这个变量不会为空,但我这样做是为了让我避开。”

此外,在无论如何都会抛出错误的代码之前抛出错误有什么意义?类似“非空断言失败!”的消息 没有比标准的空参考消息更有帮助。