TypeScript 如何编写支持枚举类型的泛型参数校验函数?
错误原因说明
- 第一个报错
'T' only refers to a type, but is being used as a value here:TS泛型是纯类型语法,编译后会被完全抹除,无法在运行时逻辑中作为值使用。 - 第二个报错
The right-hand side of an 'in' expression must not be a primitive:你把参数list的类型定义为了枚举值的联合类型(本质是字符串原始值类型),但实际需要传入的是枚举本身对应的JS对象,两者类型不匹配。
正确实现
你需要将枚举对象作为运行时参数传入,同时调整泛型约束匹配枚举对象的类型:
// 先定义允许传入的枚举对象类型联合,约束仅支持预先定义的枚举 type AllowedEnum = typeof color | typeof coverage; function getParam<T extends AllowedEnum>(value: string, enumObj: T): T[keyof T] | undefined { if (value in enumObj) { return value as T[keyof T]; } return undefined; }
使用示例
// 泛型可自动推断,无需手动声明 // 合法值返回对应枚举值,类型自动推导为 color | undefined const validColor = getParam('red', color); // 非法值返回undefined,类型自动推导为 coverage | undefined const invalidCoverage = getParam('test', coverage);
扩展说明
如果需要支持所有字符串枚举,无需限定预先定义的枚举范围,可以把泛型约束改为通用的字符串字典类型:
function getParam<T extends Record<string, string>>(value: string, enumObj: T): T[keyof T] | undefined { if (value in enumObj) return value as T[keyof T]; return undefined; }
如果需要同时支持数字枚举,把约束改为T extends Record<string, string | number>即可。
内容的提问来源于stack exchange,提问作者michaelT
相关产品推荐
相关产品推荐

