关于ts中的可选链

在 TypeScript 3.7 中引入了Optional Chaining的支持,但是项目开发的时候,存在不少滥用的情况。

比如如下代码,请考虑一下使用的正确性。

let a: null | Record<string, string> = {};

if (a?.name) {
  console.log(a?.name);
}

1. 都加上?.

因为a可能为null,所以在使用a的时候可以使用?.容错一下,但是,如果判断条件成立了,console.log中的a.name是不是肯定有值了,这时候a?.name完全没必要加。

2. 有必要使用可选链吗?

那么,对于上面的代码有必要使用可选链吗?这个问题值得考究,先看一下上面的代码经过 ts 的编译器编译之后是什么样子。

let a = {};
if (a === null || a === void 0 ? void 0 : a.name) {
  console.log(a === null || a === void 0 ? void 0 : a.name);
  // 去掉a.name的可选链
  // console.log(a.name);
}

看转义后的 js,可以明显的看到问题 1 的存在。

加了可选链的a.name,生成的代码会分别判断a是否为void 0null,此处的void 0可以看错undefined

虽然 ts 帮我们做了很好的容错,但是它会生成一大堆判断代码,比如此处的nullundefined判断。对于开发者而言,可能我们更清楚代码的类型情况,所以我们需要根据不同的场景去考虑使用使用可选链。

比如此处的a.name在使用之前需要判断a的存在,但是a只可能是nullobject中的任意一种,我们完全可以使用如下方式来改写。

if (a) {
  console.log(a.name);
}

经过 ts 的编译器编译,最终结果

if (a) {
  console.log(a.name);
}

可以发现,代码量有了很大的减少。

还有一种场景,如果确定返回的不可能为nullundefined,这时候也完全没有必要加?.,除了徒增代码量和判断逻辑,没有任何意义,例如下述 String.prototype.replace 的使用。

res.match(reg)?.[0]?.replace(reg3, '')?.replace(reg4, '<br />')?.replace(reg5, '')?.replace(reg6, '') || '';

这里 replace 肯定肯定会返回一个 string,所以加?.没有必要。

总结

可选链是一个很好的特性,但是滥用可选链会导致代码量的增加,以及不必要的判断逻辑,所以在使用可选链的时候,需要根据不同的场景去考虑使用。

如果您觉得本文对您有用,欢迎捐赠或留言~
微信支付
支付宝

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注