TypeScript数组链式调用的小技巧

大家好,我是老纪。

链式调用是一种编程技巧,它允许你将多个操作链接在一起,形成一个链。在JavaScript中,许多数组方法都返回一个新的数组,这使得你可以将多个方法链接在一起。

我们来看一个在工作中常见的示例,先过滤掉为空的元素,再返回元素的某个属性:

const arr = [{ name: "abcd" }, { name: "efgh" }, null];

const result = arr
    .filter((item) => item !== null)
    .map((item) => item.name);
console.log(result);

如果是JavaScript代码,一切好说,但当我们使用TypeScript时,IDE会提示报错,因为在mapTypeScript分析,无法确定filter之后的数组元素已经排除掉了null

image.png

 这种情况下,最简单的处理是使用非空断言符!,明确告诉TypeScript这个值一定不是null或者undefined

const result = arr
    .filter((item) => item !== null)
    .map((item) => item!.name);
console.log(result);

非空断言符非常好用,但可能会掩盖真正的问题,因为它是在用我们开发者的信用为代码背书。平时我们应该尽量避免使用它。当然,像这种一览无余的示例除外。

断言一次可能还无所谓,如果我们的链式调用再加个排序,需要多次断言,你可能就不会太爽了:

const result = arr
  .filter((item) => item != null)
  .sort((item) => (item!.name > item!.name ? 1 : -1))
  .map((item) => item!.name);

那么,还有没有更优雅一点的方式呢?

答案是有的。那就是使用类型保护

const result = arr
  .filter((item): item is User => item !== null)
  .map((item) => item.name);
console.log(result);

在这段代码中,filter方法使用了类型谓词 item is User。这告诉 TypeScript,如果 filter 方法返回 true,那么 item 一定是 User 类型,不会是 null。这样,在 map 方法中,TypeScript 就能知道 item 一定不为 null,因此你可以安全地访问item.name

这种写法看起来有些奇怪,但将这个匿名函数提取出来,就是我们熟悉的类型保护了:

const isNotNull = (item: any): item is User => {
  return item !== null;
};

const result = arr.filter(isNotNull).map((item) => item.name);
console.log(result);

此时就是再加一个sort也不怕了:

const result = arr
  .filter(isNotNull)
  .sort((item) => (item.name > item.name ? 1 : -1))
  .map((item) => item.name);

只不过,虽然这样看起来似乎更靠谱些,但是我们可能更喜欢使用Boolean写出这样的代码:

const result = arr.filter(Boolean).map((item) => item.name);
console.log(result);

可惜TypeScript没有针对filter(Boolean)做断言的优化。

折中下,我们自己封装一个支持泛型的filterNone函数来复用逻辑:

type User = { name: string };

const filterNone = <T>(item: any): item is T => {
  return item !== null && item !== undefined;
};

const result = arr.filter(filterNone<User>).map((item) => item.name);
console.log(result);

文章转自:https://juejin.cn/post/7371655419360673844

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值