TS 5.0.4中编写枚举泛型类型守卫遇报错,求解决提示
通用枚举类型守卫函数的TypeScript报错解决
问题场景
在TypeScript 5.0.4中编写通用枚举类型守卫函数时,遇到No overload matches this call错误,原代码如下:
function isEnumValue<T>(enumType: T, value: unknown): value is T[keyof T] { return Object.values(enumType).includes(value as T[keyof T]); } //-----------------------^-------------------------- // No overload matches this call enum Sort { A, B } function isSort(value: unknown): value is Sort { return isEnumValue(Sort, value); } enum Order { ASC, DESC } function isOrder(value: unknown): value is Order { return isEnumValue(Order, value); }
报错原因
TypeScript对枚举的类型处理有特殊性:
- 数字枚举会生成正向+反向映射(比如
Sort.A = 0,同时Sort[0] = "A"),导致Object.values(enumType)返回的类型包含数字和字符串,与T[keyof T]的类型不匹配 includes方法的类型校验严格,无法自动识别枚举值的实际类型范围
解决方法
方法一:类型断言绕过校验(简洁版)
直接通过类型断言告诉TypeScript,Object.values(enumType)的结果就是枚举值数组,适用于不需要区分正向/反向映射的场景:
function isEnumValue<T>(enumType: T, value: unknown): value is T[keyof T] { return (Object.values(enumType) as Array<T[keyof T]>).includes(value as T[keyof T]); } enum Sort { A, B } function isSort(value: unknown): value is Sort { return isEnumValue(Sort, value); } enum Order { ASC, DESC } function isOrder(value: unknown): value is Order { return isEnumValue(Order, value); }
方法二:过滤反向映射(精准版)
如果只需要校验枚举定义的正向值(排除数字枚举的反向字符串映射),可以添加过滤逻辑:
function isEnumValue<T extends Record<string, string | number>>(enumType: T, value: unknown): value is T[keyof T] { // 过滤掉数字枚举的反向映射(字符串类型的枚举值) const enumValues = Object.values(enumType).filter(v => { if (typeof v === 'string') { // 判断是否是反向映射的键(即对应的数字是否存在于枚举中) return !enumType.hasOwnProperty(v); } return true; }) as Array<T[keyof T]>; return enumValues.includes(value as T[keyof T]); } enum Sort { A, B } function isSort(value: unknown): value is Sort { return isEnumValue(Sort, value); } enum Order { ASC, DESC } function isOrder(value: unknown): value is Order { return isEnumValue(Order, value); }
说明
- 方法一适合大多数场景,代码简洁,无需额外逻辑
- 方法二更精准,确保只校验枚举定义的正向值,避免误判反向映射的字符串(比如数字枚举中传入"A"不会被判定为Sort类型)
内容的提问来源于stack exchange,提问作者Nainpo
相关产品推荐
相关产品推荐

