TypeScript如何实现枚举值到枚举键的反向映射?
TypeScript字符串枚举反向映射:字符串值转枚举成员
你定义了如下字符串枚举:
export enum StateEnum { STARTING = 'starting', RUNNING = 'running', STOPPING = 'stopping', STOPPED = 'stopped', DELETING = 'deleting', }
同时有一个DTO类,需要将API返回的字符串状态映射为StateEnum类型:
export class MyDTO { public state: StateEnum; constructor(infoFromApi: any) { const stateAsStringFromApi: string = infoFromApi.state; this.state = // 此处需将字符串类型的stateAsStringFromApi映射为StateEnum对应的枚举成员 } }
需求示例:当API返回的infoFromApi.state为'running'时,希望MyDTO的state等于StateEnum.RUNNING,以便后续通过switch语句判断状态:
switch (dtoObj.state) { case StateEnum.RUNNING: // 执行对应操作 case StateEnum.STOPPED: // 执行另一操作 }
以下是几种实现字符串值到枚举成员反向映射的方案:
解决方案
1. 直接赋值(最简方式)
TypeScript的字符串枚举本身支持直接用枚举值(字符串)赋值给枚举类型变量,因为字符串枚举的成员值与枚举本身的取值完全一致。你可以直接通过类型断言完成映射:
this.state = stateAsStringFromApi as StateEnum;
注意:这种方式没有合法性校验,如果API返回不在枚举范围内的字符串,编译时不会报错,运行时会得到无效的枚举值。
2. 带合法性校验的映射
如果需要确保API返回的字符串是合法枚举值,可先校验再赋值,避免无效状态:
constructor(infoFromApi: any) { const stateAsStringFromApi: string = infoFromApi.state; // 检查字符串是否属于StateEnum的有效值集合 if (Object.values(StateEnum).includes(stateAsStringFromApi as StateEnum)) { this.state = stateAsStringFromApi as StateEnum; } else { // 处理非法状态:抛出错误或设置默认值 throw new Error(`无效状态:${stateAsStringFromApi}`); // 或者设置默认值:this.state = StateEnum.STOPPED; } }
3. 封装工具函数复用
如果多个地方需要这种映射逻辑,可以封装成工具函数:
function mapToStateEnum(stateStr: string): StateEnum { if (Object.values(StateEnum).includes(stateStr as StateEnum)) { return stateStr as StateEnum; } throw new Error(`不支持的状态:${stateStr}`); } // 在DTO中调用 constructor(infoFromApi: any) { this.state = mapToStateEnum(infoFromApi.state); }
4. 使用类型守卫(增强类型安全性)
定义类型守卫函数,让TypeScript在编译阶段就能识别合法状态的类型:
function isStateEnum(value: string): value is StateEnum { return Object.values(StateEnum).includes(value as StateEnum); } // 在DTO中使用 constructor(infoFromApi: any) { const stateStr = infoFromApi.state; if (isStateEnum(stateStr)) { // 此处stateStr会被自动推断为StateEnum类型 this.state = stateStr; } else { throw new Error(`无效状态:${stateStr}`); } }
内容的提问来源于stack exchange,提问作者Pradip
相关产品推荐
相关产品推荐

