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

Why the non-null assertion operator (!) does not emit actual non-null & non-undefined checks into the resulting JS

在使用非空断言运算符时,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 代码中添加检查的原因是什么?

也就是类型断言,就是告诉编译器那个变量不为null,而不是让编译器检查那个变量。基本上,你的想法是可以的,但抛出错误并不是类型断言的目的。这就是 TypeScript 和 Javascript 之间的区别(类型检查和值检查)

non-null 断言运算符的要点是告诉 TypeScript 编译器您已经知道该变量不为空。考虑以下情况:

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

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

此外,在无论如何都会抛出错误的代码之前抛出错误有什么意义? 'The non-null assertion failed!' 之类的消息并不比标准空引用消息更有帮助。