!对象方法后打字稿中的运算符

Posted

技术标签:

【中文标题】!对象方法后打字稿中的运算符【英文标题】:! operator in typescript after object method 【发布时间】:2016-12-16 22:15:41 【问题描述】:

我有一个对象X 和一个方法getY() 返回一个对象Y 和一个方法a(),在打字稿中。 像这样的表达是什么意思:

X.getY()!.a()

我猜! 运算符用于检查null,但它具体是如何工作的呢?语言在哪里定义的?

【问题讨论】:

【参考方案1】:

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

这是一个新的 typescript 2.0 功能,您可以在 what's new 页面中阅读它,它是这样说的:

一个新的!后缀表达式运算符可用于断言其 操作数在类型为非空且非未定义的上下文中 checker 无法得出这一事实。具体来说,操作 X!产生一个 x 类型的值,其中排除了 null 和 undefined。 与 x 和 x 作为 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


编辑

There's an issue for documenting this feature: Document non-null assertion operator (!)

【讨论】:

哇。我可能写了e && e.name 几千次。谢谢 @Tope 不要将此与其他语言的“空安全运算符”(a?.b?.c?.d?)混淆。这只是告诉打字稿编译器一个变量不为空,这可能是错误的,它会在运行时崩溃 它有什么好的用例?因为如果我无论如何都必须检查 null 不符合目的吗? @StLia 如果您确定某些内容不为 null 并且您不想/不需要检查 null 怎么办? @Rishav 是的,您对 (javascript) 可选链接运算符是正确的,对于 (typescript) 非空断言运算符也是正确的。但它们也意味着完全不同的东西。第一个说“我不确定,它可以为空,但如果不继续......”但后者说“我 100% 确定它不为空”。【参考方案2】:

非空断言运算符:!

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

这是一个简单的例子:

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')
    

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

【讨论】:

以上是关于!对象方法后打字稿中的运算符的主要内容,如果未能解决你的问题,请参考以下文章

如何在打字稿中避免这种符号“| undefined”?

打字稿中的通用对象类型

如何将方法的泛型类型限制为打字稿中的对象?

对象打字稿中的条件类型

更新可观察打字稿中的数组值

如何从打字稿中的json响应中获取日期对象