如何基于Enum键动态分配TypeScript对象的对应接口类型?
TypeScript 枚举与接口类型映射实现方案
核心需求实现
- animals对象键与专属接口的类型映射
通过类型映射(Mapped Types) + 条件类型(Conditional Types),为枚举的每个键匹配对应的专属接口,无专属接口时自动回退到iBaseAnimal:
// 定义枚举值到专属接口的映射表 type AnimalTypeMap = { [ANIMALS.Shark]: iShark; [ANIMALS.Parrot]: iParrot; [ANIMALS.Snail]: iSnail; }; // 构建animals对象的类型:遍历ANIMALS所有键,匹配对应类型,无则用iBaseAnimal type AnimalsObject = { [K in keyof typeof ANIMALS]: K extends keyof AnimalTypeMap ? AnimalTypeMap[K] : iBaseAnimal; };
- getAnimal参数支持枚举值联合类型
直接将参数类型设为ANIMALS即可,TypeScript会自动识别枚举值的联合类型:
interface iAnimals { animals: AnimalsObject; getAnimal(animalKey: ANIMALS): AnimalsObject[keyof AnimalsObject]; }
完整代码示例
// 基础枚举与接口定义 enum ANIMALS { Shark = 'shark', Parrot = 'parrot', Snail = 'snail', Tiger = 'tiger' // 无专属接口的测试项 } interface iBaseAnimal { name: string; age: number; } interface iShark extends iBaseAnimal { finCount: number; } interface iParrot extends iBaseAnimal { canTalk: boolean; } interface iSnail extends iBaseAnimal { hasShell: boolean; } // 类型映射配置 type AnimalTypeMap = { [ANIMALS.Shark]: iShark; [ANIMALS.Parrot]: iParrot; [ANIMALS.Snail]: iSnail; }; type AnimalsObject = { [K in keyof typeof ANIMALS]: K extends keyof AnimalTypeMap ? AnimalTypeMap[K] : iBaseAnimal; }; // 最终接口实现 interface iAnimals { animals: AnimalsObject; getAnimal(animalKey: ANIMALS): AnimalsObject[keyof AnimalsObject]; } // 实例测试 const zoo: iAnimals = { animals: { shark: { name: 'Bruce', age: 5, finCount: 8 }, parrot: { name: 'Polly', age: 2, canTalk: true }, snail: { name: 'Gary', age: 1, hasShell: true }, tiger: { name: 'Tony', age: 3 } // 自动匹配iBaseAnimal类型 }, getAnimal(key) { return this.animals[key]; } }; // 类型验证:shark会提示finCount属性,tiger仅提示iBaseAnimal属性 console.log(zoo.animals.shark.finCount); console.log(zoo.animals.tiger.name);
关键说明
AnimalTypeMap作为枚举与专属接口的映射表,新增动物时只需在此处添加对应关系,无需修改其他类型定义。AnimalsObject通过Mapped Type自动遍历枚举所有键,结合条件类型完成类型匹配,避免手动维护每个键的类型。getAnimal参数使用ANIMALS类型,自动获得枚举值的联合类型约束,防止传入非法值。
内容的提问来源于stack exchange,提问作者Héctor León
相关产品推荐
相关产品推荐

