打字稿是否支持?运营商?(而且,它叫什么?)

Mar*_*itt 255 typescript

Typescript目前(或有计划)支持安全导航操作员?.

即:

var thing = foo?.bar
// same as:
var thing = (foo) ? foo.bar : null;
Run Code Online (Sandbox Code Playgroud)

此外,这个运营商有一个更常见的名称(它很难谷歌).

A. *_*K-R 133

不如单一的好吗?,但它的工作原理:

var thing = foo && foo.bar || null;
Run Code Online (Sandbox Code Playgroud)

您可以根据需要使用尽可能多的&&:

var thing = foo && foo.bar && foo.bar.check && foo.bar.check.x || null;
Run Code Online (Sandbox Code Playgroud)

  • 只要语句为真,&&就会进行评估.如果为true,则返回最后一个值.如果为false,则返回评估为false的第一个值.那可能是0,null,false等.|| 返回计算结果为true的第一个值. (31认同)
  • 如果定义了条形但是求值为false(如布尔值false或零),则不能正常工作. (30认同)

Don*_*nut 99

我在TypeScript语言规范中找不到任何引用.

至于在CoffeeScript中调用此运算符的内容,它被称为存在运算符(具体地说,是存在运算符的"访问变量").

CoffeeScript关于运算符的文档:

存在运算符的存取器变体?.可用于在属性链中吸收空引用..在基值可能为null未定义的情况下,使用它代替点访问器.

因此,存在运算符存取器变体似乎是引用此运算符的正确方法; 而且TypeScript目前似乎不支持它(尽管其他人表达了对此功能的渴望).

  • "存在运算符的存取变体".自然.如此吸引人,几乎不可能忘记.:).感谢非常彻底的回答. (18认同)
  • 在其他一些语言中,它称为“猫王”运算符 (4认同)
  • https://github.com/Microsoft/TypeScript/issues/16问题已移至此处. (3认同)
  • Angular 在它的模板中实现了这一点:https://angular.io/guide/template-syntax#the-safe-navigation-operator----and-null-property-paths (2认同)
  • 它是针对TypeScript 3.7.0宣布的(https://github.com/microsoft/TypeScript/issues/16#issuecomment-515160784) (2认同)

Fen*_*ton 81

这在ECMAScript可选链接规范中定义,因此在讨论时我们应该参考可选链接.可能的实施:

const result = a?.b?.c;
Run Code Online (Sandbox Code Playgroud)

这个问题的长期和短期是TypeScript团队正在等待ECMAScript规范收紧,因此它们的实现在未来可能不会中断.如果他们现在实现了某些东西,那么如果ECMAScript重新定义他们的规范,最终将需要进行重大更改.

请参阅可选链接规范

在某些东西永远不会成为标准JavaScript的情况下,TypeScript团队可以按照自己的意愿实现,但是对于未来的ECMAScript添加,他们希望保留语义,即使它们提供早期访问,因为它们具有许多其他功能.

短切

因此,所有JavaScripts时髦运算符都可用,包括类型转换,如...

var n: number = +myString; // convert to number
var b: bool = !!myString; // convert to bool
Run Code Online (Sandbox Code Playgroud)

手动解决方案

但回到这个问题.我有一个很明显的例子,说明如何在JavaScript(以及TypeScript)中执行类似的操作,尽管我绝对不会建议它是一个优雅的,因为你真正追求的功能.

(foo||{}).bar;
Run Code Online (Sandbox Code Playgroud)

所以,如果fooundefined的结果是undefined,如果foo被定义,并有一个名为财产bar具有价值,结果是该值.

在JSFiddle上举了一个例子.

对于较长的例子,这看起来很粗略.

var postCode = ((person||{}).address||{}).postcode;
Run Code Online (Sandbox Code Playgroud)

链功能

如果您仍然急需一个较短的版本,而规格仍然悬而未决,我会在某些情况下使用这种方法.它计算表达式并返回默认值,如果链条不能满足或最终空/未定义(注意,!=在这里很重要,我们希望使用!==,因为我们希望有点积极的杂耍这里).

function chain<T>(exp: () => T, d: T) {
    try {
        let val = exp();
        if (val != null) {
            return val;
        }
    } catch { }
    return d;
}

let obj1: { a?: { b?: string }} = {
    a: {
        b: 'c'
    }
};

// 'c'
console.log(chain(() => obj1.a.b, 'Nothing'));

obj1 = {
    a: {}
};

// 'Nothing'
console.log(chain(() => obj1.a.b, 'Nothing'));

obj1 = {};

// 'Nothing'
console.log(chain(() => obj1.a.b, 'Nothing'));

obj1 = null;

// 'Nothing'
console.log(chain(() => obj1.a.b, 'Nothing'));
Run Code Online (Sandbox Code Playgroud)


bas*_*rat 42

在github上有一个开放功能请求,你可以发表你的意见/愿望:https://github.com/Microsoft/TypeScript/issues/16


Jos*_*e A 28

编辑:感谢fracz评论,我已经更新了答案.

TypeScript 2.0发布?.它与!.(C#中的Safe Navigator)不一样

有关详细信息,请参阅此答案:

/sf/answers/2721262561/

这只会告诉编译器该值不为null或未定义.这不会检查值是null还是未定义.

TypeScript非空断言运算符

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

  • 这回答了我的问题.我知道吗?来自c#并在打字稿中尝试过.它没用,但我看到了!存在但不知道它做了什么.我想知道它是否相同,谷歌搜索,并找到了我的方式,这个问题告诉我,不,他们是不同的. (5认同)
  • 与`?`不同,因为它*断言*定义了值.`?`应该默默地失败/评估为假.无论如何,很高兴知道. (4认同)

sup*_*ary 11

TypeScript 3.7支持Elvis(?。)可选链接运算符。

您可以使用它来检查null值:cats?.miows如果cats为null或未定义,则返回null。

您也可以将其用于可选方法调用:cats.doMiow?.(5)如果存在,将调用doMiow。

也可以访问媒体资源:cats?.['miows']

参考:https : //devblogs.microsoft.com/typescript/announcing-typescript-3-7-beta/

  • 请纠正我,但 Elvis 运算符至少在 Kotlin 中是“?:”。你有参考吗? (2认同)
  • 它将很快在纯 JS 中得到支持 - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining (2认同)

Veg*_*ter 10

?.TypeScript 版本2.0不支持运算符.

所以我使用以下功能:

export function o<T>(someObject: T, defaultValue: T = {} as T) : T {
    if (typeof someObject === 'undefined' || someObject === null)
        return defaultValue;
    else
        return someObject;
}
Run Code Online (Sandbox Code Playgroud)

用法如下:

o(o(o(test).prop1).prop2
Run Code Online (Sandbox Code Playgroud)

另外,您可以设置默认值:

o(o(o(o(test).prop1).prop2, "none")
Run Code Online (Sandbox Code Playgroud)

它在Visual Studio中与IntelliSense配合得非常好.

  • 或者您可以将其称为`elvis &lt;T&gt;`;-) (4认同)
  • Simon_Weaver,我称它为“悲伤的小丑”:o( (2认同)

zor*_*404 9

终于来了!

这里有一些例子:

// properties
foo?.bar
foo?.bar()
foo?.bar.baz()
foo?.bar?.baz()

// indexing
foo?.[0]
foo?.['bar']

// check if a function is defined before invoking
foo?.()
foo.bar?.()
foo?.bar?.()
Run Code Online (Sandbox Code Playgroud)

但这与您的假设并不完全相同。

而不是评估

foo?.bar
Run Code Online (Sandbox Code Playgroud)

对于这个我们都习惯于编写的小代码片段

foo ? foo.bar : null
Run Code Online (Sandbox Code Playgroud)

它实际上评估为

(foo === null || foo === undefined) ?
    undefined :
    foo.bar
Run Code Online (Sandbox Code Playgroud)

它适用于所有 falsey 值,如空字符串、0 或 false。

我只是没有解释为什么他们不编译它 foo == null