这是在ECMAScript可选链接规范中定义的,因此我们在讨论时可能应该参考可选链接。可能的实现:
const result = a?.b?.c;
这样做的长处和短处是TypeScript团队正在等待ECMAScript规范收紧,因此它们的实现将来可能会不断发展。如果他们现在实施了某些措施,那么如果ECMAScript重新定义其规范,最终将需要进行重大更改。
请参阅可选的链接规范
在某些东西永远不会成为标准JavaScript的地方,TypeScript团队可以按照自己的意愿实施,但是对于将来的ECMAScript增补,他们希望保留语义,即使它们提供了早期访问权限,就像许多其他功能一样。
捷径
因此,所有JavaScript时髦的运算符都可用,包括类型转换,例如...
var n: number = +myString; // convert to number
var b: bool = !!myString; // convert to bool
手动解决方案
但是回到问题。我有一个令人费解的示例,说明了如何在JavaScript(以及TypeScript)中执行类似的操作,尽管我绝对不建议它是您真正追求的功能。
(foo||{}).bar;
所以,如果foo
是undefined
的结果是undefined
,如果foo
被定义,并有一个名为财产bar
具有价值,结果是该值。
我在JSFiddle上举了一个例子。
对于更长的示例,这看起来很粗略。
var postCode = ((person||{}).address||{}).postcode;
连锁功能
如果您迫切希望使用更短的版本,而规范仍然悬而未决,则在某些情况下,我会使用此方法。它计算表达式并返回默认值,如果链条不能满足或者达到零/不确定的结束(注意,!=
在这里很重要,我们不希望使用!==
,因为我们希望有点积极的杂耍这里)。
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'));