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

TypeScript中如何按类型过滤包含多类型的对象数组?

问题:如何让过滤函数支持包含LayoutChangeAction的任意联合类型数组?

我有一个通过type属性过滤对象数组的函数:

export const retrieveLayoutChangeActions = (data: GetOperations['included']) =>
  data.filter(d => d.type === 'layoutChangeAction') as LayoutChangeAction[];

data参数可能包含LayoutChangeAction[]之外的更多类型,比如(LayoutChangeAction | Product)[]。我想扩展类型定义,让它支持任何包含LayoutChangeAction的类型。

我尝试用泛型实现:

export const retrieveLayoutChangeActions = <T extends LayoutChangeAction>(data: T[]) =>
  data.filter(d => d.type === 'layoutChangeAction') as LayoutChangeAction[];

但出现报错:TS2345: Argument of type '(LayoutChangeAction | Product)[]' is not assignable to parameter of type 'LayoutChangeAction[]'.

相关类型定义如下(各类型通过type属性唯一标识):

interface LayoutChangeAction extends BaseResponse<'layoutChangeAction'> {
  type: 'layoutChangeAction';
  /* 独有属性... */
}

interface Product extends BaseResponse<'product'> {
  type: 'product';
  /* 独有属性... */
}

解决方案

你需要调整泛型约束,让T可以是包含LayoutChangeAction的任意类型,而非仅LayoutChangeAction的子类型。通过自定义类型守卫配合泛型,既能保证类型安全,又能支持多种联合类型输入:

优化后的代码

// 自定义类型守卫,精准判断对象是否为LayoutChangeAction
const isLayoutChangeAction = (item: unknown): item is LayoutChangeAction => {
  return typeof item === 'object' && item !== null && (item as LayoutChangeAction).type === 'layoutChangeAction';
};

export const retrieveLayoutChangeActions = <T extends { type: string }>(data: T[]) =>
  data.filter(isLayoutChangeAction);

核心说明

  • 泛型约束T extends { type: string }:允许传入任何带有type字符串属性的对象数组,完美兼容LayoutChangeAction | Product这类联合类型数组。
  • 类型守卫isLayoutChangeAction:让TypeScript自动推断过滤后数组的类型为LayoutChangeAction[],无需手动添加类型断言,避免潜在的类型错误。

可选:更严格的泛型约束

如果要确保传入的数组元素只能是LayoutChangeAction或带有其他type值的对象,可以进一步收紧泛型:

export const retrieveLayoutChangeActions = <T extends LayoutChangeAction | { type: Exclude<string, 'layoutChangeAction'> }>(data: T[]) =>
  data.filter(isLayoutChangeAction);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 09:25:23