在打字稿中,什么是! (感叹号/砰)操作员提领会员?

当查看一个tslint规则的源代码时,我遇到以下声明:

if (node.parent!.kind === ts.SyntaxKind.ObjectLiteralExpression) { return; } 

注意! 运算符在node.parent之后。 有趣!

我首先尝试用我当前安装的TS版本(1.5.3)在本地编译文件。 由此产生的错误指向爆炸的确切位置:

 $ tsc --noImplicitAny memberAccessRule.ts noPublicModifierRule.ts(57,24): error TS1005: ')' expected. 

接下来我升级到了最新的TS(2.1.6),它没有问题地编译它。 所以它似乎是TS 2.x的function。 但是这个编译完全忽略了爆炸,导致了下面的JS:

 if (node.parent.kind === ts.SyntaxKind.ObjectLiteralExpression) { return; } 

我的Google fu已经失败了。

什么是TS的感叹号运算符,它是如何工作的?

这是非空断言运算符。 这是告诉编译器的一种方法:“这个expression式不能为null或者在这里没有undefined ,所以不要抱怨它是nullundefined的可能性。 有时候types检查器本身不能做出这个决定。

这里解释:

一个新的! 后缀修饰expression式操作符可以用于断言其操作数在types检查器无法推断该事实的上下文中是非空的和非未定义的。 具体来说,操作x! 产生x的types的值,其中nullundefined排除。 类似于将<T>xx as T断言types, 在发出的JavaScript代码中简单地删除非null断言运算符。

我觉得在这个解释中使用“assert”这个术语有点误导。 从开发者主张的angular度来看,它是“断言”的,而不是在testing即将进行的意义上。 最后一行确实表明它没有发出JavaScript代码。

路易斯的答案很好,但我想我会尽量简洁地总结一下:

bang运算符告诉编译器暂时放松它可能要求的“非空”约束。 它对编译器说:“作为开发者,我比你更了解这个variables现在不能为空”。