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

如何让TypeWithAddedProperty支持数组类型的条件泛型处理?

解决方案:用条件类型适配数组与单个对象场景

当然可以搞定这个问题!咱们的核心目标就是让TypeWithAddedProperty能智能区分输入是单个对象还是数组,分别返回对应的扩展类型。

第一步:修改TypeWithAddedProperty为条件类型

我们可以利用TypeScript的条件类型+类型推断,来实现根据输入类型动态调整返回类型:

export type TypeWithAddedProperty<T> = 
  // 如果T是数组类型,提取数组元素类型U,返回元素带新增属性的数组
  T extends Array<infer U> 
    ? Array<U & { addedProperty: string }> 
    : // 非数组类型,直接返回原类型与新增属性的交叉类型
      T & { addedProperty: string };

这里的infer U是关键,它会自动提取数组的元素类型U,然后我们给U加上addedProperty后再重新包裹成数组,完美匹配数组场景的预期。

第二步:修正函数的参数类型与返回断言

接下来需要给函数的data参数指定类型T,同时为了让TypeScript的控制流分析能正确匹配条件类型的返回,我们需要在两个分支里加上类型断言:

function addSomeStuff<T>(data: T): TypeWithAddedProperty<T> { 
  if (Array.isArray(data)) { 
    return data.map(element => { 
      return { ...element, addedProperty: 'something' };
    }) as TypeWithAddedProperty<T>;
  } else { 
    return { ...data, addedProperty: 'something' } as TypeWithAddedProperty<T>;
  } 
}

验证效果

现在不管是传入单个对象还是数组,返回类型都符合预期了:

// 单个对象场景
const user = { id: 1, name: 'Alice' };
const extendedUser = addSomeStuff(user);
// extendedUser 类型:{ id: number; name: string } & { addedProperty: string }

// 数组场景
const users = [{ id: 2, name: 'Bob' }, { id: 3, name: 'Charlie' }];
const extendedUsers = addSomeStuff(users);
// extendedUsers 类型:Array<{ id: number; name: string } & { addedProperty: string }>

为什么需要类型断言?

TypeScript的控制流分析虽然强大,但对于条件类型的复杂推断有时候会“转不过弯来”——它没法自动识别map返回的数组正好是条件类型里定义的Array<U & {addedProperty: string}>,所以我们需要用as TypeWithAddedProperty<T>来帮它确认返回值类型的正确性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:26:54