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

TypeScript中基于指定键将数组转换为对象时的正确类型推断方案

这个问题我之前也碰到过!核心问题在于你原来的映射类型只是把数组元素的联合类型直接赋值给了每个键,没有建立起type键和对应元素类型的关联。咱们来一步步解决它:

首先,保留你已经写好的数组定义(这部分没问题,as const确保了每个元素的类型都是字面量精确类型):

interface MyObject { type: string; [key: string]: any }
const createObjectList = <T extends ReadonlyArray<MyObject>>(items: T) => items;
const objectList = createObjectList([
  { type: 'a', value: 'foo' },
  { type: 'b', value: 10 },
] as const)

接下来,要修改ObjectDictionary的类型定义,关键是用Extract工具类型从联合类型里筛选出对应type的具体元素类型:

type ObjectDictionary = {
  [K in typeof objectList[number]['type']]: 
    Extract<typeof objectList[number], { type: K }>;
};

const typed: ObjectDictionary = undefined as any;
// 现在 typed.a.value 会被正确推断为 'foo' 类型(即 string 字面量)
// typed.b.value 会被推断为 10 类型(即 number 字面量)

为什么这样能行?

  • typeof objectList[number]是数组所有元素的联合类型:{ type: 'a', value: 'foo' } | { type: 'b', value: 10 }
  • 当我们遍历每个K(也就是'a'和'b')时,Extract<联合类型, { type: K }>会从联合类型中精准筛选出type属性等于K的那个元素类型,而不是直接用整个联合类型。

如果你想把这个逻辑封装成通用工具,方便复用,可以写成:

// 通用类型:把带有唯一type属性的数组转换成字典类型
type ArrayToDictionary<T extends ReadonlyArray<{ type: string }>> = {
  [K in T[number]['type']]: Extract<T[number], { type: K }>;
};

// 复用这个类型
type ObjectDictionary = ArrayToDictionary<typeof objectList>;

这样不管你有多少个不同type的数组元素,都能正确生成每个键对应专属类型的字典了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 18:37:40