TS:将数组类型转换为目标键值对对象类型的问题
如何将带const断言的数组转换为精确键值对类型?
你遇到的问题是Record类型会把所有键和值合并成联合类型,导致每个键都能对应所有可能的值,不符合预期。要实现键值对的精确映射,需要用映射类型结合Extract工具类型逐个匹配数组元素:
第一步:定义精确的目标类型
const MY_CONST = [ { id: 1, name: "ITEM_1" }, { id: 2, name: "ITEM_2" } ] as const; // 生成精确的键值对类型 type ConvertedConst = { // 遍历数组中每个元素的id字面量类型 [K in typeof MY_CONST[number]["id"]]: // 提取出id等于当前K的元素,再取它的name类型 Extract<typeof MY_CONST[number], { id: K }>["name"] };
此时ConvertedConst的类型就是你想要的:
type ConvertedConst = { 1: "ITEM_1"; 2: "ITEM_2"; }
第二步:正确实现数组转对象的逻辑
用reduce转换时,需要给初始值指定ConvertedConst类型(或用类型断言),否则TS会把空对象{}推断为任意空对象类型,导致赋值报错:
const converted = MY_CONST.reduce((acc, curr) => { acc[curr.id] = curr.name; return acc; }, {} as ConvertedConst);
为什么之前的方法不行?
你之前用的Record<MyConstItem["id"], MyConstItem["name"]>,本质是把1 | 2作为键集合、"ITEM_1" | "ITEM_2"作为值集合批量映射,它不会关联单个键和对应值的关系,因此每个键都会被分配所有值的联合类型。
而映射类型+Extract的方式,会为每个id单独匹配对应的name,从根源保证了类型的精确性。
内容的提问来源于stack exchange,提问作者Arsen
相关产品推荐
相关产品推荐

