我有一个对象
X
,其方法getY()
返回一个对象Y
,其方法为a()
,在打字稿中。
像这样的表达是什么意思:
X.getY()!.a()
我猜
!
运算符是用来检查 null 的,但是它具体是如何工作的呢?语言中在哪里定义的?
它被称为“非空断言运算符”,它告诉编译器
x.getY()
不为空。
这是一个新的 TypeScript 2.0 功能,您可以在 新增功能 页面中阅读相关内容,内容如下:
新的!后缀表达式运算符可用于断言其 操作数在类型所在的上下文中非空且非未定义 检查者无法得出这一事实的结论。具体来说,操作 X!生成 x 类型的值,排除 null 和 undefined。 类似于 x 和 x as T 形式的类型断言,! 非空断言运算符在发出时被简单地删除 JavaScript 代码。
// Compiled with --strictNullChecks
function validateEntity(e?: Entity) {
// Throw exception if e is null or invalid entity
}
function processEntity(e?: Entity) {
validateEntity(e);
let s = e!.name; // Assert that e is non-null and access name
}
null | undefined
这是一个简单的例子来说明它的作用:
let nullable1: null | number;
let nullable2: undefined | string;
let foo = nullable1! // type foo: number
let fooz = nullable2! // type fooz: string
它基本上从类型中删除了
null | undefined
我什么时候使用这个?
Typescript 已经非常擅长推断类型,例如使用类型保护:
let nullable: null | number | undefined;
if (nullable) {
const foo = nullable; // ts can infer that foo: number, since if statements checks this
}
然而有时我们会遇到如下情况:
type Nullable = null | number | undefined;
let nullable: Nullable;
validate(nullable);
// Here we say to ts compiler:
// I, the programmer have checked this and foo is not null or undefined
const foo = nullable!; // foo: number
function validate(arg: Nullable) {
// normally usually more complex validation logic
// but now for an example
if (!arg) {
throw Error('validation failed')
}
}
我个人的建议是尽可能避免使用这个操作符。让编译器完成静态检查代码的工作。然而,在某些情况下,尤其是在供应商代码中,使用此运算符是不可避免的。
当变量可以是 null/undefined 类型并且您正在该变量上执行需要它为非 null/非未定义的函数时,它消除了打字稿编译错误。
function getValue(): string | undefined {
return "MyStr"; // TS assumes getValue can return undefined as well
//return undefined;
//return OutsidePlugin(); // The plugin can return both string and undefined, e.g.
}
let value = getValue();
console.log('value length: ' + value.length); //value.length can requires non-undefined
这将生成以下 Typescript 编译错误:
'value' is possibly 'undefined'.
非空断言运算符只是一个快速逃生口:
console.log('value length: ' + value!.length); //TS, I assure you it's non-undefined