TypeScript:实现枚举自动合并并提供正确类型支持与自动补全
TypeScript 多枚举合并方案(支持类型提示与自动补全)
需求说明
需要实现一个能合并20+个枚举的方案,保留所有键值对,同时减少重复代码,并且支持IDE自动补全。比如现有两个枚举:
示例枚举
mammals.ts
enum Mammals { Humans = 'Humans', Bats = 'Bats', Dolphins = 'Dolphins' }
reptiles.ts
enum Reptiles { Snakes = 'Snakes', Alligators = 'Alligators', Lizards = 'Lizards' }
目标是生成一个OverAll总枚举,包含上述所有键值对,合法键(如OverAll.Humans、OverAll.Snakes)能正常访问,非法键(如OverAll.Kekes)会被TypeScript报错,同时IDE能提供自动补全。
用户尝试了以下合并函数,但无法正确推导类型:
const combineEnums = <T extends { [key: string]: any }[]>(...enums: T): { [key: string]: any } => { const combined: { [key: string]: any } = {}; enums.forEach((enumObj) => { Object.keys(enumObj).forEach((key) => { combined[key] = enumObj[key]; }); }); return combined; };
解决方案
1. 类型安全的通用合并函数
通过泛型推导让函数自动识别合并后的类型,保留完整的自动补全:
type MergeEnums<T extends readonly Record<string, string>[]> = { [K in keyof T[number]]: T[number][K] }; const combineEnums = <T extends readonly Record<string, string>[]>(...enums: T): MergeEnums<T> => { return enums.reduce((acc, curr) => ({ ...acc, ...curr }), {} as MergeEnums<T>); }; // 使用示例 const OverAll = combineEnums(Mammals, Reptiles);
优势:
- 支持任意数量的枚举传入
- IDE自动补全所有合并后的键名
- 重复键会被后续传入的枚举覆盖(若存在冲突)
2. 简洁版:交叉类型 + Object.assign
如果不需要函数封装,直接用交叉类型结合Object.assign更简单:
type OverAllType = typeof Mammals & typeof Reptiles; const OverAll = Object.assign({}, Mammals, Reptiles) as OverAllType;
这种方式适合枚举数量固定的场景,同样能保留完整的类型提示。
3. 生成严格枚举类型
如果需要生成真正的enum类型而非对象,可以用类型别名结合枚举值:
// 仅保留枚举值类型 type OverAll = Mammals | Reptiles; // 保留键值对映射同时生成类型 const OverAll = { ...Mammals, ...Reptiles } as const; type OverAll = typeof OverAll[keyof typeof OverAll];
这种方式适合需要严格枚举类型约束的场景,避免重复代码。
内容的提问来源于stack exchange,提问作者RuSaG0
相关产品推荐
相关产品推荐

