liuww

typescript编译时,当我们开启严格模式时,下面的代码就会报错:

function doSomething(x: string | null) {
    console.log("Hello, " + x.toUpperCase());
}

编译错误:

hello.ts:56:29 - error TS2531: Object is possibly 'null'.

56     console.log("Hello, " + x.toUpperCase());
                               ~

当我们在调用变量x的方法时,增加后缀!和?时,这个编译错误都会消失:

x!.toUpperCase() x?.toUpperCase()

那这两者到底有什么区别呢?

那我们运行分别运行下代码就可以看出端倪:

  • 后缀是?

    function doSomething(x: string | null) {
        console.log("Hello, " + x?.toUpperCase());
    }
    
    doSomething(null);
    

​ 输出是:

Hello, undefined

  • 后缀是!

    function doSomething(x: string | null) {
        console.log("Hello, " + x!.toUpperCase());
    }
    
    doSomething(null);
    

    输出是:

    Uncaught TypeError TypeError: Cannot read properties of null (reading 'toUpperCase')

结论:

  • 后缀是!,只是告诉typescript编译器对于nullundefined不做显示的检查,生成的js文件中还是x.toUpperCase(),如果此时x为null,那么就会出现运行时异常
  • 后缀是?,代表是一个空判断,只有非空是,才会执行x.toUpperCase(),生成的js文件中是增加了null或者undefined判断的,生成的js是(x === null || x === void 0 ? void 0 : x.toUpperCase())

相关文章: