Typescript目前(或计划)是否支持安全导航操作符?。
ie:
var thing = foo?.bar
// same as:
var thing = (foo) ? foo.bar : null;
此外,这个操作符是否有更常见的名称(很难为谷歌)。
Typescript目前(或计划)是否支持安全导航操作符?。
ie:
var thing = foo?.bar
// same as:
var thing = (foo) ? foo.bar : null;
此外,这个操作符是否有更常见的名称(很难为谷歌)。
当前回答
终于来了!
下面是一些例子:
// 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?.()
但这和你的假设不完全一样。
而不是评估
foo?.bar
对于这个我们都习惯编写的小代码片段
foo ? foo.bar : null
它的值实际上是
(foo === null || foo === undefined) ?
undefined :
foo.bar
它适用于所有假值,如空字符串,0或false。
我只是没有一个解释,为什么他们不编译为foo == null
其他回答
正如之前所回答的,目前它仍在考虑中,但到目前为止它已经死在水里几年了。
在现有答案的基础上,以下是我能想到的最简洁的手动版本:
斯菲德尔
function val<T>(valueSupplier: () => T): T {
try { return valueSupplier(); } catch (err) { return undefined; }
}
let obj1: { a?: { b?: string }} = { a: { b: 'c' } };
console.log(val(() => obj1.a.b)); // 'c'
obj1 = { a: {} };
console.log(val(() => obj1.a.b)); // undefined
console.log(val(() => obj1.a.b) || 'Nothing'); // 'Nothing'
obj1 = {};
console.log(val(() => obj1.a.b) || 'Nothing'); // 'Nothing'
obj1 = null;
console.log(val(() => obj1.a.b) || 'Nothing'); // 'Nothing'
它只是在缺少属性错误时无声地失败。它退回到确定默认值的标准语法,也可以完全省略。
虽然这适用于简单的情况,但如果您需要更复杂的东西,例如调用函数然后访问结果上的属性,那么任何其他错误也会被忽略。糟糕的设计。
在上述情况下,这里发布的其他答案的优化版本是更好的选择:
斯菲德尔
function o<T>(obj?: T, def: T = {} as T): T {
return obj || def;
}
let obj1: { a?: { b?: string }} = { a: { b: 'c' } };
console.log(o(o(o(obj1).a)).b); // 'c'
obj1 = { a: {} };
console.log(o(o(o(obj1).a)).b); // undefined
console.log(o(o(o(obj1).a)).b || 'Nothing'); // 'Nothing'
obj1 = {};
console.log(o(o(o(obj1).a)).b || 'Nothing'); // 'Nothing'
obj1 = null;
console.log(o(o(o(obj1).a)).b || 'Nothing'); // 'Nothing'
一个更复杂的例子:
o(foo(), []).map((n) => n.id)
你也可以反过来使用类似Lodash' _.get()的东西。它是简洁的,但编译器将无法判断使用的属性的有效性:
console.log(_.get(obj1, 'a.b.c'));
操作员吗?。在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;
}
用法是这样的:
o(o(o(test).prop1).prop2
另外,你可以设置一个默认值:
o(o(o(o(test).prop1).prop2, "none")
它与Visual Studio中的智能感知一起工作得非常好。
我一般不推荐这种方法(注意性能问题),但是您可以使用扩散操作符来浅克隆一个对象,然后您可以访问该对象上的属性。
const person = { personId: 123, firstName: 'Simon' };
const firstName = { ...person }.firstName;
这是可行的,因为'firstName'类型是通过'传播'的。
我将使用这个最频繁的时候,我有一个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;
typescript推断类型的方式可能有一些边缘情况,这不会被编译,但这通常应该是可行的。
更新:是的,现在支持了!
它刚刚与TypeScript 3.7一起发布:https://devblogs.microsoft.com/typescript/announcing-typescript-3-7/
它被称为可选链接:https://devblogs.microsoft.com/typescript/announcing-typescript-3-7/#optional-chaining
有以下内容:
let x = foo?.bar.baz();
等价于:
let x = (foo === null || foo === undefined) ?
undefined :
foo.bar.baz();
旧的答案
在github上有一个开放的功能请求,你可以在那里发表你的意见/愿望:https://github.com/Microsoft/TypeScript/issues/16
现在可以了,请看用户“甜甜圈”的回答。
旧的回答: 关于布尔运算符的标准JavaScript行为可能会有所帮助。布尔方法在比较对象时不返回true或false,但在or情况下,第一个值等于true。
虽然不如单身好,但还是管用的:
var thing = foo && foo.bar || null;
你可以随心所欲地使用&&:
var thing = foo && foo.bar && foo.bar.check && foo.bar.check.x || null;
也可以使用默认值:
var name = person && person.name || "Unknown user";