!对象方法后的操作符

use*_*922 38 object operators typescript

我有一个对象X,一个方法getY()返回一个Y带有方法的对象a(),在typescript中.这个表达式是什么意思:

X.getY()!.a()
Run Code Online (Sandbox Code Playgroud)

我猜!运算符用于检查null,但具体如何工作?语言中定义的位置是什么?

Nit*_*mer 66

它被称为"非空断言运算符",它告诉编译器x.getY()不为空.

这是一个新的打字稿2.0功能,您可以在页面中阅读它,这里是它的内容:

一个新的!post-fix表达式运算符可用于断言其操作数在类型检查器无法推断该事实的上下文中为非null且非未定义.具体来说,操作x!生成x类型的值,其中包含null和undefined.类似于形式x和x的类型断言为T,!在发出的JavaScript代码中简单地删除了非null断言运算符.

// 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
}
Run Code Online (Sandbox Code Playgroud)

编辑

记录此功能存在一个问题:记录非空断言运算符(!)

  • @Tope请勿将此与其他语言的“空安全运算符”(a?.b?.c?.d?)混淆。这只是告诉Typescript编译器变量不是null,它可能是false,并且会在运行时崩溃 (17认同)
  • 哇。我可能写了“e && e.name”几千次。谢谢 (5认同)
  • 它的一个好的用例是什么?因为如果我无论如何都必须检查是否为空,这是否违背了目的? (4认同)
  • @StLia如果你确定某些东西不为空并且你不想/不需要检查空值怎么办? (3认同)
  • @Rishav是的,您对(javascript)可选链接运算符的看法是正确的,并且您对(typescript)非空断言运算符的看法也是正确的。但它们也意味着完全不同的事情。第一个说“我不确定,它可以为空,但如果不继续......”,但后者说“我 100% 确定它不为空”。 (2认同)

Wil*_*een 42

非空断言运算符:!

  • 你告诉 TS 编译器变量的值不是null | undefined
  • 当您掌握了 TS 编译器所缺乏的知识时,请使用它。

这是一个简单的例子来说明它的作用:

let nullable1: null | number;
let nullable2: undefined | string;

let foo  = nullable1! // type foo: number
let fooz = nullable2! // type fooz: string
Run Code Online (Sandbox Code Playgroud)

它基本上null | undefined从类型中删除


我什么时候使用这个?

Typescript 已经非常擅长推断类型,例如使用类型保护:

let nullable: null | number | undefined;

if (nullable) {
    const foo = nullable; // ts can infer that foo: number, since if statements checks this
}
Run Code Online (Sandbox Code Playgroud)

然而,有时我们会遇到如下情况:

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')
    }
}
Run Code Online (Sandbox Code Playgroud)

我个人的建议是尽可能避免使用此运算符。让编译器完成静态检查代码的工作。然而,在某些情况下,尤其是在供应商代码中,使用此运算符是不可避免的。