如何在TypeScript中基于一个枚举构建另一个枚举?
TypeScript枚举自动映射的惯用实现方式
在TypeScript中,原生枚举是静态编译的,无法直接动态生成成员。要实现声明式将Element的键自动映射为xxxMagic形式并合并到技能枚举,最符合惯用风格的方案是用对象+类型别名模拟枚举,既能保留类型安全,又能灵活实现自动映射。
实现方案:对象+类型别名模拟枚举
这种方式通过纯TypeScript代码完成,无需额外工具,完全满足声明式映射的需求:
enum Element { Air, Fire, Earth, Water } // 1. 定义自定义基础技能 const baseSkills = { Unarmed: 0, LightArmor: 1, // 可添加更多自定义技能 } as const; // 2. 自动生成元素魔法技能:Element的键 + "Magic" const elementMagicSkills = Object.fromEntries( // 过滤掉枚举的数值反向映射键 Object.keys(Element).filter(key => isNaN(Number(key))).map(key => [ `${key}Magic`, // 确保魔法技能的数值在基础技能之后 Object.values(baseSkills).length + Element[key as keyof typeof Element] ]) ) as const; // 3. 合并基础技能与魔法技能,得到完整的Skills集合 const Skills = { ...baseSkills, ...elementMagicSkills } as const; // 4. 定义Skills的类型,模拟枚举的类型约束 type Skills = typeof Skills[keyof typeof Skills]; // 使用示例 const mySkill: Skills = Skills.AirMagic; // 类型安全,支持自动提示 console.log(Skills.FireMagic); // 输出:2
方案优势
- 声明式映射:无需手动重复编写
AirMagic、FireMagic等成员,完全基于Element枚举自动生成 - 类型安全:通过类型别名
Skills实现与原生枚举一致的类型约束,编辑器支持自动补全 - 灵活性高:可以自由添加/修改自定义技能,映射逻辑可按需调整
原生枚举的局限性(可选补充)
如果一定要使用原生enum语法,TypeScript本身不支持动态生成枚举成员,只能通过外部代码生成脚本(比如在构建前读取Element枚举的定义,自动拼接生成Skills枚举的代码)。但这种方式需要额外的构建流程支持,并非TypeScript本身的惯用写法,因此更推荐上面的对象模拟方案。
内容的提问来源于stack exchange,提问作者Christopher LaChance
相关产品推荐
相关产品推荐

