在 TypeScript 中,常常存在一个对象可能是 undefined
或 null
的情况。如果试图直接使用这样的对象,很可能会造成 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
被认为一定是非 undefined
或 null
类型的。(至于 TypeScript 会认为这个变量是什么类型的,就要看这个变量除了 undefined | null
的类型之外,还可能是什么类型的了)
当然,不难看出,这个运算符只是一个编译时帮助编译器理解类型用的辅助手段,本身并不是一个语法糖。因此,在 TypeScript 转化成 JavaScript 的过程中,这里的运算符会直接被去掉。optional!.length
生成的就是 optional.length
,没有生成任何额外的东西。