如何用TypeScript从多个联合类型创建Record的组合键类型?
实现TypeScript多联合类型的组合键类型
固定数量联合类型的组合(以3个为例)
直接利用TypeScript的模板字面量类型特性,它会自动遍历联合类型的所有可能组合,生成拼接后的字符串联合类型:
// 定义基础联合类型 type Eggs = "Scrambled" | "Fried" | "Poached" type Drink = "Coffee" | "Orange Juice" | "Milk" type Meat = "Bacon" | "Sausage" | "Steak" // 实现Combined类型,拼接三个联合类型的所有组合 type Combined<T extends string, U extends string, V extends string> = `${T}_${U}_${V}`; // 生成所有组合的键类型 type combinedType = Combined<Eggs, Drink, Meat>; // 创建Record类型 type myRecord = Record<combinedType, number>; // 此时myObj必须包含所有组合键,缺少或多余都会触发类型报错 const myObj: myRecord = { "Scrambled_Coffee_Bacon": 2.3, "Scrambled_Coffee_Sausage": 4.1, "Scrambled_Coffee_Steak": 5.5, "Scrambled_Orange Juice_Bacon": 3.0, // ... 需补充所有其他组合键值对 };
通用版本(支持任意数量联合类型)
如果需要支持不确定数量的联合类型,可以用递归的模板字面量类型实现:
// 定义基础联合类型 type Eggs = "Scrambled" | "Fried" | "Poached" type Drink = "Coffee" | "Orange Juice" | "Milk" type Meat = "Bacon" | "Sausage" | "Steak" // 递归实现通用Combined类型 type Combined<T extends string[]> = T extends [infer First extends string, ...infer Rest extends string[]] ? Rest extends [] ? First : `${First}_${Combined<Rest>}` : never; // 传入联合类型数组生成组合键类型 type combinedType = Combined<[Eggs, Drink, Meat]>; // 创建Record类型 type myRecord = Record<combinedType, number>; // 同样需要定义所有组合键值对 const myObj: myRecord = { "Scrambled_Coffee_Bacon": 2.3, // ... 所有其他组合 };
原理说明
TypeScript的模板字面量类型与联合类型结合时,会自动展开所有可能的组合,生成完整的字符串联合类型。递归版本则通过解构数组类型,逐步拼接每个联合类型的所有可能值,最终覆盖所有组合场景。
内容的提问来源于stack exchange,提问作者Tim Reistetter
相关产品推荐
相关产品推荐

