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

如何从泛型对象数组构建TypeScript映射类型?

解决方案

首先,你不能用ObjWithPath<any>[]作为blackBox的参数类型——any会直接丢失每个元素的泛型参数T的类型信息。我们需要让函数接收泛型数组类型,结合TypeScript的映射类型和条件类型来实现需求。

1. 明确ObjWithPath的基础定义

假设你的ObjWithPath是交叉类型实现:

type ObjWithPath<T> = T & { _path: string };

2. 实现blackBox的类型推导

通过泛型数组保留元素的类型细节,再用映射类型将_path转为键、对应泛型参数T转为值:

function blackBox<T extends ObjWithPath<any>[]>(
  arr: T
): { 
  [K in T[number]['_path']]: 
    Extract<T[number], { _path: K }> extends ObjWithPath<infer U> 
      ? U 
      : never 
} {
  // 函数逻辑示例:用reduce聚合为目标结构
  return arr.reduce((acc, item) => {
    acc[item._path] = item;
    return acc;
  }, {} as any);
}

3. 验证效果

传入具体数组时,返回类型会自动推导为预期的键值对结构:

// 定义带_path的具体对象
const userItem: ObjWithPath<{ name: string; age: number }> = {
  name: "Josh",
  age: 30,
  _path: "user"
};

const configItem: ObjWithPath<{ theme: string; autoSave: boolean }> = {
  theme: "dark",
  autoSave: true,
  _path: "config"
};

// 返回类型自动推导为:{ user: { name: string; age: number }, config: { theme: string; autoSave: boolean } }
const result = blackBox([userItem, configItem]);

// 类型校验生效:result.user.age 是number类型,result.config.theme是string类型

关键逻辑说明

  • T extends ObjWithPath<any>[]:让参数保留每个数组元素的具体类型,避免any抹平类型差异。
  • T[number]['_path']:提取所有元素_path值的联合类型,作为映射类型的键集合。
  • Extract<T[number], { _path: K }>:从元素联合类型中筛选出_path等于当前键K的元素,再通过infer U提取该元素的泛型参数T类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 03:08:12