TypeScript如何基于枚举key而非值实现switch case并保障类型校验?
方案1:基于现有枚举改造,约束入参为枚举键类型
你只需要把入参的类型从string收窄为keyof typeof COLOR,就能同时获得智能提示和漏case编译检测能力,代码示例如下:
export enum COLOR { BLUE= 'blue', DARK_BLUE='blue', RED= 'red', } // 入参类型收窄为枚举所有键的联合:'BLUE' | 'DARK_BLUE' | 'RED' function foo(colorKey: keyof typeof COLOR) { switch (colorKey) { // 写case时TS会自动提示所有可选的枚举键,写错直接编译报错 case 'BLUE': // 执行BLUE对应逻辑 break case 'DARK_BLUE': // 执行DARK_BLUE对应逻辑 break case 'RED': // 执行RED对应逻辑 break default: // 穷尽性检查:新增枚举成员时这里会编译报错,提示补全case const _exhaustiveCheck: never = colorKey throw new Error(`未处理的颜色键: ${_exhaustiveCheck}`) } }
调用函数时会自动提示可选的枚举键,传非法值直接报错,完全符合需求。
方案2:用as const常量对象替代枚举(更灵活)
如果不想在case里写字符串字面量,后续枚举改动需要批量修改的场景更推荐这个方案,完全避免枚举的局限性:
// 用as const定义常量,替代枚举 export const COLOR = { BLUE: 'blue', DARK_BLUE: 'blue', RED: 'red', } as const // 按需导出键类型和值类型 export type COLOR_KEY = keyof typeof COLOR // 键的联合类型,用于switch匹配 export type COLOR_VALUE = typeof COLOR[COLOR_KEY] // 值的联合类型,用于取值场景 function foo(colorKey: COLOR_KEY) { switch (colorKey) { case 'BLUE': // 可以正常取到对应的值使用 console.log('对应颜色值为', COLOR.BLUE) break case 'DARK_BLUE': console.log('对应颜色值为', COLOR.DARK_BLUE) break case 'RED': console.log('对应颜色值为', COLOR.RED) break default: const _exhaustiveCheck: never = colorKey throw new Error(`未处理的颜色键: ${_exhaustiveCheck}`) } }
这个方案你既可以用键类型做匹配,也可以正常拿到定义的颜色值使用,新增成员只需要修改COLOR对象,所有相关类型自动更新,不需要额外维护两套定义。
内容的提问来源于stack exchange,提问作者Yanis Yakuza
相关产品推荐
相关产品推荐

