TypeScript Non-null Assertion

TypeScript

在 TypeScript 中,常常存在一个对象可能是 undefinednull 的情况。如果试图直接使用这样的对象,很可能会造成 TypeScript 的报错(在 --strictNullChecks 开启的情况下)。这本身是一个正确的行为,也可以在编译时帮助开发者避免一些不必要的错误。

然而,在实际的开发中,不免遇到这样的情况:在某些特定的生命周期中,开发者可以很明确的知道某一个值不会是 undefined 或者 null。然而,这样的前置条件 TypeScript 本身并不知情。此时,为了防止 TypeScript 报错,就需要通过某些显式的方法,声明这一情况。

最常见的方案,是通过 as 来强制类型转化。比如:

function throwIfUndefined(input: any) {
  if (typeof input === 'undefined') throw new Error('Undefined!');
}
function handler(optional?: string) {
  throwIfUndefined(optional);
  console.log((optional as string).length);
}

TypeScript 提供了一个 Non-null assertion 运算符:!.,就是用于上述情景的。具体来说:

function handler(optional?: string) {
  throwIfUndefined(optional);
  console.log(optional!.length);
}

上面这样写之后,TypeScript 就不会报错了。optional 被认为一定是非 undefinednull 类型的。(至于 TypeScript 会认为这个变量是什么类型的,就要看这个变量除了 undefined | null 的类型之外,还可能是什么类型的了)

当然,不难看出,这个运算符只是一个编译时帮助编译器理解类型用的辅助手段,本身并不是一个语法糖。因此,在 TypeScript 转化成 JavaScript 的过程中,这里的运算符会直接被去掉。optional!.length 生成的就是 optional.length,没有生成任何额外的东西。