在 Typescript 中,什么是 !取消引用成员时的(感叹号/爆炸)运算符?
In Typescript, what is the ! (exclamation mark / bang) operator when dereferencing a member?
在查看 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;
}
我的Google fu 到目前为止让我失望了。
TS的感叹号运算符是什么,它是如何工作的?
那是 non-null 断言运算符。这是一种告诉编译器的方法 "this expression cannot be null
or undefined
here, so don't complain about the possibility of it being null
or undefined
." 有时类型检查器无法自己做出决定。
说明here:
A new !
post-fix expression operator may be used to assert that its operand is non-null and non-undefined in contexts where the type checker is unable to conclude that fact. Specifically, the operation x!
produces a value of the type of x
with null
and undefined
excluded. Similar to type assertions of the forms <T>x
and x as T
, the !
non-null assertion operator is simply removed in the emitted JavaScript code.
我发现在该解释中使用术语 "assert" 有点误导。它是 "assert" 的意思是 开发人员断言它 ,而不是要执行测试的意思。最后一行确实表明它不会导致 JavaScript 代码被发出。
Louis 的回答很好,但我想我会尽量简洁地总结一下:
bang 运算符告诉编译器暂时放宽它可能需要的 "not null" 约束。它对编译器说:"As the developer, I know better than you that this variable cannot be null right now".
非空断言运算符
使用非空断言运算符,我们可以明确地告诉编译器表达式具有 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代码
注意JS不知道Non-null assertion operator的概念,因为这是TS的特性
"use strict";
function simpleExample(nullableArg) {
const normal = nullableArg;
const operatorApplied = nullableArg;
}
简答
非 null 断言运算符 (!) 帮助编译器确定此变量不是 null 或未定义的变量。
let obj: { field: SampleType } | null | undefined;
... // some code
// the type of sampleVar is SampleType
let sampleVar = obj!.field; // we tell compiler we are sure obj is not null & not undefined so the type of sampleVar is SampleType
在查看 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;
}
我的Google fu 到目前为止让我失望了。
TS的感叹号运算符是什么,它是如何工作的?
那是 non-null 断言运算符。这是一种告诉编译器的方法 "this expression cannot be null
or undefined
here, so don't complain about the possibility of it being null
or undefined
." 有时类型检查器无法自己做出决定。
说明here:
A new
!
post-fix expression operator may be used to assert that its operand is non-null and non-undefined in contexts where the type checker is unable to conclude that fact. Specifically, the operationx!
produces a value of the type ofx
withnull
andundefined
excluded. Similar to type assertions of the forms<T>x
andx as T
, the!
non-null assertion operator is simply removed in the emitted JavaScript code.
我发现在该解释中使用术语 "assert" 有点误导。它是 "assert" 的意思是 开发人员断言它 ,而不是要执行测试的意思。最后一行确实表明它不会导致 JavaScript 代码被发出。
Louis 的回答很好,但我想我会尽量简洁地总结一下:
bang 运算符告诉编译器暂时放宽它可能需要的 "not null" 约束。它对编译器说:"As the developer, I know better than you that this variable cannot be null right now".
非空断言运算符
使用非空断言运算符,我们可以明确地告诉编译器表达式具有 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代码
注意JS不知道Non-null assertion operator的概念,因为这是TS的特性
"use strict";
function simpleExample(nullableArg) {
const normal = nullableArg;
const operatorApplied = nullableArg;
}
简答
非 null 断言运算符 (!) 帮助编译器确定此变量不是 null 或未定义的变量。
let obj: { field: SampleType } | null | undefined;
... // some code
// the type of sampleVar is SampleType
let sampleVar = obj!.field; // we tell compiler we are sure obj is not null & not undefined so the type of sampleVar is SampleType