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

TypeScript中如何根据类型过滤联合类型数组?

解决TypeScript联合类型数组的类型判断与过滤问题

对于TypeA[] | TypeB[]这种联合类型数组,你可以通过类型守卫来收窄类型,从而准确判断数组属于哪种类型并进行过滤。下面是具体实现方案:

方案1:使用自定义类型守卫函数

自定义类型守卫能让代码逻辑更清晰,尤其适合需要多次判断的场景:

interface TypeA {
  attribute1: string
  attribute2: string
}

interface TypeB {
  attribute3: string
  attribute4: string
}

// 判断数组是否为TypeA[]类型
function isTypeAArray(arr: unknown): arr is TypeA[] {
  // 先判断是否为数组,再检查第一个元素是否包含TypeA的特征属性
  return Array.isArray(arr) && arr.length > 0 && 'attribute1' in arr[0];
}

// 判断数组是否为TypeB[]类型
function isTypeBArray(arr: unknown): arr is TypeB[] {
  return Array.isArray(arr) && arr.length > 0 && 'attribute3' in arr[0];
}

function filterFunc(obj: TypeA[] | TypeB[]) {
  // 处理空数组的特殊情况(空数组同时符合两种类型,可根据需求调整逻辑)
  if (obj.length === 0) {
    return [];
  }

  if (isTypeAArray(obj)) {
    return obj.filter(item => item.attribute1 === 'test');
  }

  if (isTypeBArray(obj)) {
    return obj.filter(item => item.attribute3 === 'something');
  }

  // 兜底返回(理论上不会走到这里,因为输入类型是明确的联合类型)
  return [];
}

方案2:直接在条件中进行类型收窄

如果不需要复用判断逻辑,可以直接在if条件里通过属性检查完成类型收窄:

interface TypeA {
  attribute1: string
  attribute2: string
}

interface TypeB {
  attribute3: string
  attribute4: string
}

function filterFunc(obj: TypeA[] | TypeB[]) {
  if (obj.length > 0 && 'attribute1' in obj[0]) {
    // 此时TypeScript会自动将obj推断为TypeA[]
    return obj.filter(item => item.attribute1 === 'test');
  }

  if (obj.length > 0 && 'attribute3' in obj[0]) {
    // 此时TypeScript会自动将obj推断为TypeB[]
    return obj.filter(item => item.attribute3 === 'something');
  }

  // 空数组或无法判断时返回空数组
  return [];
}

关键说明

  • 为什么要检查数组长度?因为空数组[]同时满足TypeA[]和TypeB[]的类型约束,直接检查属性会导致报错,所以需要先处理空数组场景。
  • 类型收窄的核心:TypeScript会根据in操作符的检查结果,自动推断变量的具体类型,从而允许你访问对应类型的属性(比如item.attribute1或item.attribute3)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 20:12:35