在查看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的特征。 但是这个翻译完全忽略了爆炸,导致了以下JS:
if (node.parent.kind === ts.SyntaxKind.ObjectLiteralExpression) {
return;
}
到目前为止,我的谷歌已经失败了。
什么是TS的感叹号操作符,它是如何工作的?
答案 0 :(得分:364)
那是非空断言运算符。这是告诉编译器的一种方式,这个表达式不能在null
或undefined
,所以不要抱怨它是null
或{{{}} 1}}#&34;有时,类型检查器无法自行做出决定。
解释here:
新的
undefined
post-fix表达式运算符可用于在类型检查器无法推断该事实的上下文中断言其操作数是非null且非未定义的。具体而言,操作!
会生成x!
类型的值,并排除x
和null
。与表单undefined
和<T>x
的类型断言类似,只在发出的JavaScript代码中删除x as T
非空断言运算符。
我发现使用术语&#34;断言&#34;在那个解释中有点误导。它是&#34;断言&#34;在某种意义上开发人员断言,而不是在将要执行测试的意义上。最后一行确实表明它不会发出任何JavaScript代码。
答案 1 :(得分:79)
路易斯&#39;答案很好,但我想我会试着简洁地总结一下:
bang操作符告诉编译器暂时放松&#34; not null&#34;它可能要求的约束。它告诉编译器:&#34;作为开发人员,我比你更了解这个变量现在不能为空&#34;。
答案 2 :(得分:5)
使用非null断言运算符,我们可以明确告诉编译器某个表达式具有null
或undefined
以外的值。当编译器无法确定类型但我们比编译器提供更多信息时,这很有用。
TS代码
function simpleExample(nullableArg: number | undefined | null) {
const normal: number = nullableArg;
// Compile err:
// Type 'number | null | undefined' is not assignable to type 'number'.
// Type 'undefined' is not assignable to type 'number'.(2322)
const operatorApplied: number = nullableArg!;
// compiles fine because we tell compiler that null | undefined are excluded
}
已编译的JS代码
请注意,由于这是TS功能,因此JS不了解Non-null断言运算符的概念
"use strict";
function simpleExample(nullableArg) {
const normal = nullableArg;
const operatorApplied = nullableArg;
}