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

时间:2019-02-27 10:32:05

标签: typescript null undefined

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

function fun1(node: SomeType | undefined) {
    fun2(node!);
}

应转换为:

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

但是,就像文档所说的那样,它只会被转译为:

function fun1(node) {
    fun2(node);
}

为什么会这样?不将支票添加到输出JS代码中的原因是什么?

2 个答案:

答案 0 :(得分:0)

这是类型断言,这意味着您告诉编译器该变量不为null,而不是要求编译器检查该变量。基本上,您的想法是可能的,但是引发错误不是类型声明的目的。这就是TypeScript和Javascript(类型检查和值检查)之间的区别

答案 1 :(得分:0)

非null断言运算符的作用是告诉TypeScript编译器您已经知道该变量不为null。请考虑以下情形:

function fun1(node: SomeType | undefined) {
    throwIfUndefined(node);
    node!.fun2();
}

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

此外,在将仍然抛出错误的代码之前抛出错误的意义何在?诸如“非空断言失败!”的消息没有比标准的空引用消息有用的东西。