typescript 打字稿是否支持?。操作员?(还有,它叫什么?)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15260732/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-11 01:00:39  来源:igfitidea点击:

Does Typescript support the ?. operator? (And, what's it called?)

typescript

提问by Marty Pitt

Does Typescript currently (or are there plans to) support the safe navigationoperator of ?.

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

ie:

IE:

var thing = foo?.bar
// same as:
var thing = (foo) ? foo.bar : null;

Also, is there a more common name for this operator (it's incedibly hard to google for).

此外,这个运营商是否有更常见的名称(谷歌很难找到)。

采纳答案by Donut

Update: it is supported as of TypeScript 3.7 and called Optional chaining: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#optional-chaining

更新:从 TypeScript 3.7 开始支持它并称为可选链https: //www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#optional-chaining

I can't find any reference to it whatsoever in the TypeScript language specification.

我在TypeScript 语言规范中找不到任何对它的引用。

As far as what to call this operator in CoffeeScript, it's called the existential operator(specifically, the "accessor variant" of the existential operator).

至于在 CoffeeScript 中如何调用这个运算符,它被称为存在运算符(具体来说,是存在运算符的“访问器变体”)。

From CoffeeScript's documentation on Operators:

来自CoffeeScript 关于 Operators 的文档

The accessor variant of the existential operator ?.can be used to soak up null references in a chain of properties. Use it instead of the dot accessor .in cases where the base value may be nullor undefined.

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

So, the accessor variant of the existential operatorappears to be the proper way to refer to this operator; and TypeScript does not currently appear to support it (although others have expressed a desire for this functionality).

因此,存在运算符访问器变体似乎是引用该运算符的正确方式;并且 TypeScript 目前似乎不支持它(尽管其他人表达了对这个功能的渴望)。

回答by A. K-R

Not as nice as a single ?, but it works:

不如单个 ? 好,但它有效:

var thing = foo && foo.bar || null;

You can use as many && as you like:

您可以使用任意数量的 && :

var thing = foo && foo.bar && foo.bar.check && foo.bar.check.x || null;

回答by Fenton

This is defined in the ECMAScript Optional Chaining specification, so we should probably refer to optional chainingwhen we discuss this. Likely implementation:

这是在 ECMAScript Optional Chaining 规范中定义的,所以当我们讨论这个时,我们可能应该参考可选链。可能的实现:

const result = a?.b?.c;

The long and short of this one is that the TypeScript team are waiting for the ECMAScript specification to get tightened up, so their implementation can be non-breaking in the future. If they implemented something now, it would end up needing major changes if ECMAScript redefine their specification.

总而言之,TypeScript 团队正在等待 ECMAScript 规范收紧,因此他们的实现将来可以不间断。如果他们现在实施某些东西,如果 ECMAScript 重新定义他们的规范,最终将需要进行重大更改。

See Optional Chaining Specification

请参阅可选链规范

Where something is never going to be standard JavaScript, the TypeScript team can implement as they see fit, but for future ECMAScript additions, they want to preserve semantics even if they give early access, as they have for so many other features.

在某些永远不会成为标准 JavaScript 的地方,TypeScript 团队可以按照他们认为合适的方式实施,但是对于未来的 ECMAScript 添加,他们希望保留语义,即使他们提供早期访问权限,就像他们对许多其他功能一样。

Short Cuts

捷径

So all of JavaScripts funky operators are available, including the type conversions such as...

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

var n: number = +myString; // convert to number
var b: bool = !!myString; // convert to bool

Manual Solution

手动解决方案

But back to the question. I have an obtuse example of how you can do a similar thing in JavaScript (and therefore TypeScript) although I'm definitely not suggesting it is a graceful as the feature you are really after.

但是回到问题。我有一个关于如何在 JavaScript(以及 TypeScript)中做类似事情的笨拙示例,尽管我绝对不是建议它像您真正追求的功能那样优雅。

(foo||{}).bar;

So if foois undefinedthe result is undefinedand if foois defined and has a property named barthat has a value, the result is that value.

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

I put an example on JSFiddle.

在 JSFiddle 上举了一个例子

This looks quite sketchy for longer examples.

对于较长的示例,这看起来很粗略。

var postCode = ((person||{}).address||{}).postcode;

Chain Function

链式功能

If you are desperate for a shorter version while the specification is still up in the air, I use this method in some cases. It evaluates the expression and returns a default if the chain can't be satisfied or ends up null/undefined (note the !=is important here, we don'twant to use !==as we want a bit of positive juggling here).

如果您在规范仍然悬而未决时迫切需要更短的版本,我会在某些情况下使用这种方法。它计算表达式并返回默认值,如果链条不能满足或者达到零/不确定的结束(注意,!=在这里很重要,我们希望使用!==,因为我们希望有点积极的杂耍这里)。

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

回答by basarat

Update: Yes its supported now!

更新:是的,现在支持!

It just got released with TypeScript 3.7 : https://devblogs.microsoft.com/typescript/announcing-typescript-3-7/

它刚刚与 TypeScript 3.7 一起发布:https: //devblogs.microsoft.com/typescript/annoucing-typescript-3-7/

It is called optional chaining: https://devblogs.microsoft.com/typescript/announcing-typescript-3-7/#optional-chaining

它被称为可选链https: //devblogs.microsoft.com/typescript/annoucing-typescript-3-7/#optional-chaining

With it the following:

有了它:

let x = foo?.bar.baz(); 

is equivalent to:

相当于:

let x = (foo === null || foo === undefined) ?
    undefined :
    foo.bar.baz();

Old answer

旧答案

There is an open feature request for this on github where you can voice your opinion / desire : https://github.com/Microsoft/TypeScript/issues/16

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

回答by Jose A

Edit Nov. 13, 2019!

2019 年 11 月 13 日编辑!

As of November 5, 2019 TypeScript 3.7 has shipped and it now supports?.the optional chaining operator !!!

截至 2019 年 11 月 5 日,TypeScript 3.7 已经发布,现在支持?.可选链操作符!!!

https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#optional-chaining

https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#optional-chaining



For Historical Purposes Only:

仅用于历史目的:

Edit:I have updated the answer thanks to fracz comment.

编辑:由于 fracz 评论,我已经更新了答案。

TypeScript 2.0 released !.It's not the same as ?.(Safe Navigator in C#)

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

See this answer for more details:

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

https://stackoverflow.com/a/38875179/1057052

https://stackoverflow.com/a/38875179/1057052

This will only tell the compiler that the value is not null or undefined. This will notcheck if the value is null or undefined.

这只会告诉编译器该值不为空或未定义。这不会检查值是否为空或未定义。

TypeScript Non-null assertion operator

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
}

回答by superluminary

The Elvis (?.) Optional Chaining Operator is supported in TypeScript 3.7.

TypeScript 3.7 支持 Elvis (?.) Optional Chaining Operator。

You can use it to check for null values: cats?.miowsreturns null if cats is null or undefined.

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

You can also use it for optional method calling: cats.doMiow?.(5)will call doMiow if it exists.

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

Property access is also possible: cats?.['miows'].

也可以访问属性:cats?.['miows'].

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

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

回答by VeganHunter

Operator ?.is not supported in TypeScript version 2.0.

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

So I use the following function:

所以我使用以下功能:

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

the usage looks like this:

用法如下所示:

o(o(o(test).prop1).prop2

plus, you can set a default value:

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

o(o(o(o(test).prop1).prop2, "none")

It works really well with IntelliSense in Visual Studio.

它与 Visual Studio 中的 IntelliSense 配合得非常好。

回答by zoran404

It's finally here!

终于来了!

Here are a few examples:

这里有一些例子:

// 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?.()

But it doesn't work exactly the same as your assumption.

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

Instead of evaluating

而不是评估

foo?.bar

to this little code snippet we are all used to writing

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

foo ? foo.bar : null

it actually evaluates to

它实际上评估为

(foo === null || foo === undefined) ?
    undefined :
    foo.bar

which works for all the falsey values like an empty string, 0 or false.

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

I just don't have an explanation as to why they don't compile it to foo == null

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

回答by phidias

We created this util method while working on Phonetradrwhich can give you type-safe access to deep properties with Typescript:

我们在使用Phonetradr时创建了这个 util 方法,它可以让您使用 Typescript 对深层属性进行类型安全的访问:

/**
 * Type-safe access of deep property of an object
 *
 * @param obj                   Object to get deep property
 * @param unsafeDataOperation   Function that returns the deep property
 * @param valueIfFail           Value to return in case if there is no such property
 */
export function getInSafe<O,T>(obj: O, unsafeDataOperation: (x: O) => T, valueIfFail?: any) : T {
    try {
        return unsafeDataOperation(obj)
    } catch (error) {
        return valueIfFail;
    }
}

//Example usage:
getInSafe(sellTicket, x => x.phoneDetails.imeiNumber, '');

//Example from above
getInSafe(foo, x => x.bar.check, null);

回答by Simon_Weaver

I don't generally recommend this approach (watch out for performance concerns), but you can use the spread operator to shallow clone an object, which you can then access the property on.

我通常不推荐这种方法(注意性能问题),但是您可以使用扩展运算符来浅克隆一个对象,然后您可以访问该对象的属性。

 const person = { personId: 123, firstName: 'Simon' };
 const firstName = { ...person }.firstName;

This works because the type of 'firstName' is 'propagated' through.

这是有效的,因为“firstName”的类型是“传播”的。

I'll use this most frequently when I have a find(...)expression that can return null and I need a single property from it:

当我有一个find(...)可以返回 null的表达式并且我需要它的一个属性时,我会最频繁地使用它:

 // this would cause an error (this ID doesn't exist)
 const people = [person];
 const firstName2 = people.find(p => p.personId == 999).firstName;

 // this works - but copies every property over so raises performance concerns
 const firstName3 = { ...people.find(p => p.personId == 999) }.firstName;

There may be some edge cases with the way typescript infers types and this won't compile, but this should generally work.

打字稿推断类型的方式可能存在一些边缘情况,这将无法编译,但这通常应该有效。