146

我正在尝试使用带有数组而不是对象的可选链接,但不知道如何做到这一点:

这就是我想要做的myArray.filter(x => x.testKey === myTestKey)?[0]。还尝试使用函数进行类似的操作:

let x = {a: () => {}, b: null}
console.log(x?b());

但它给出了这样的错误,所以如何将它与数组或函数一起使用。

4

5 回答 5

292

您需要在使用可选链接.之后放置一个:?

myArray.filter(x => x.testKey === myTestKey)?.[0]

游乐场链接

单独使用?会使编译器认为您正在尝试使用条件运算符(然后它会引发错误,因为它:稍后看不到)

可选链不仅仅是 TypeScript 的东西——它也是一个用纯 JavaScript完成的提案。

它可以与上面的括号表示法一起使用,但也可以与点表示法属性访问一起使用:

const obj = {
  prop2: {
    nested2: 'val2'
  }
};

console.log(
  obj.prop1?.nested1,
  obj.prop2?.nested2
);

并使用函数调用:

const obj = {
  fn2: () => console.log('fn2 running')
};

obj.fn1?.();
obj.fn2?.();

于 2020-01-07T07:08:39.090 回答
21

在官方文档的新功能页面上进行了一些搜索后才找到它

使用数组的正确方法是在.之后添加?

所以它会像

myArray.filter(x => x.testKey === myTestKey)?.[0]

我想进一步说明我的上述问题案例到底发生了什么。

myArray.filter(x => x.testKey === myTestKey)?[0]

转译为

const result = myArray.filter(x => x.testKey === myTestKey) ? [0] : ;

因此它会引发错误,因为 : 之后缺少某些内容,并且您可能不希望将代码转换为此。

感谢Certain Performance的回答,我学到了关于打字稿的新东西,尤其是工具https://www.typescriptlang.org/play/index.html

于 2020-01-07T07:09:37.997 回答
10

我在 Edge Chromium 84 上测试的 ECMA 262 (2020) 可以在没有 TypeScript 转译器的情况下执行可选链接运算符:

// All result are undefined
const a = {};

console.log(a?.b);
console.log(a?.["b-foo-1"]);
console.log(a?.b?.());

// Note that the following statements throw exceptions:
a?.(); // TypeError: a is not a function
a?.b(); // TypeError: a?.b is not a function

可使用:Chrome 80+、Firefox 74+

于 2020-08-16T19:32:19.163 回答
2

好吧,即使我们找到了正确的语法,代码对我来说也没有多大意义。

上面代码中的可选链接确保myArray.filter(x => x.testKey === myTestKey)is notnull和 not的结果undefined(您可以查看 TS 输出)。但无论如何这是不可能的,因为filter方法的结果总是一个array. 由于 JavaScript 不会抛出“超出数组边界”,因此当您尝试访问任何索引时始终是安全的 -undefined如果此元素不存在,您将得到。

更清楚的例子:

const myArray: string[] = undefined
console.log(myArray.filter(x => x)?.[0]) //throws Cannot read property 'filter' of undefined
//in this example the optional chaining protects us from undefined array
const myArray: string[] = undefined
console.log(myArray?.filter(x => x)[0]) //outputs "undefined"
于 2020-07-09T14:11:10.693 回答
-1

函数不必在对象内部,您也可以使用可选链接运行函数,如下所示:

someFunction?.();

如果someFunction存在,它将运行,否则它将跳过执行并且不会出错。

这种技术实际上非常有用,特别是如果您使用可重用组件并且某些组件可能没有此功能。

于 2021-12-22T15:43:51.867 回答