You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从对象数组的单个对象字段类型中过滤null?

解决TypeScript中合并数组后移除类型中的null问题

问题场景

我们有两个数组需要合并,其中nums的类型被标注为(number | null)[]但实际不存在null元素:

const strs = ['zero', 'one', 'two', 'three', 'four'];

// 模拟类型为`(T | null)[]`但实际无null元素的场景
const nums: (number | null)[] = [0, 1, 2, 3, 4];

const zipped = strs.map((str, i) => ({ str, num: nums[i] }));

合并后的zipped类型为{ str: string, num: number | null }[],但我们确定num绝不会为null,需要从类型中移除null。

为什么之前的方法无效

直接使用filter或者针对num的类型谓词函数,TypeScript无法自动推断整个数组元素的类型变化——因为类型谓词只作用于num字段,而非整个对象。

解决方案

1. 为数组元素编写类型谓词函数

针对整个对象编写类型谓词,明确判断num不为null时,元素的类型是{ str: string; num: number }:

const isNumNonNull = (item: { str: string; num: number | null }): item is { str: string; num: number } => {
  return item.num !== null;
};

const checkedNull = zipped.filter(isNumNonNull);
// checkedNull的类型为{ str: string; num: number }[]

2. 类型断言(谨慎使用)

如果能完全保证数据安全,可以直接用类型断言强制修改数组类型:

const checkedNull = zipped.filter(({ num }) => num !== null) as { str: string; num: number }[];

3. 从源头修正类型

既然确定nums中没有null元素,在合并前就将其类型断言为number[],这样合并后的zipped类型直接符合预期:

const numsAsserted = nums as number[];
const zipped = strs.map((str, i) => ({ str, num: numsAsserted[i] }));
// zipped的类型为{ str: string; num: number }[]

内容的提问来源于stack exchange,提问作者eloy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 23:25:12