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
Does Typescript support the ?. operator? (And, what's it called?)
提问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.
存在运算符的访问器变体
?.
可用于吸收属性链中的空引用。.
在基值可能为null或undefined 的情况下,使用它代替点访问器。
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 foo
is undefined
the result is undefined
and if foo
is defined and has a property named bar
that has a value, the result is that value.
所以,如果foo
是undefined
的结果是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
// 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?.miows
returns 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.
打字稿推断类型的方式可能存在一些边缘情况,这将无法编译,但这通常应该有效。