TypeScript:基于泛型Filter类型解决动态函数调用类型错误
解决TypeScript泛型Filter类型下动态函数调用的类型错误
你遇到的核心问题是:通过f0.ftype动态调用config对象中的函数时,TypeScript无法识别f0.ftype和f0.value的类型关联,导致类型校验失败。以下是具体的问题原因和解决方案:
问题根源
f0的类型是Filter<keyof FilterValues>,这是一个联合类型(包含Filter<"ip">和Filter<"magic">两种子类型)。此时c[f0.ftype]会被推断为联合函数类型((data: string) => string) | ((data: number) => string),而f0.value是string | number的联合值。TypeScript对联合函数的调用有严格限制:只能传入所有分支参数类型的交集,但string和number的交集是never,因此触发类型错误。
解决方案
方案1:用泛型函数保留类型关联
通过泛型函数捕获单个Filter的具体类型,让TypeScript明确ftype和value的一一对应关系:
type FilterValues = { ip: string; magic: number }; type Config = { [key in keyof FilterValues]: (data: FilterValues[key]) => string; }; const c: Config = { ip: (data: string) => data, magic: (data: number) => data.toString(), }; type Filter<T extends keyof FilterValues> = { ftype: T; value: FilterValues[T]; }; const f: Array<Filter<keyof FilterValues>> = [ { ftype: "magic", value: 6 }, { ftype: "ip", value: "1.2.3.4" }, ]; const f0 = f[0]; // 泛型函数处理单个Filter实例 function processFilter<T extends keyof FilterValues>(filter: Filter<T>) { console.log(c[filter.ftype](filter.value)); } processFilter(f0); // 类型校验通过
方案2:用类型守卫缩小类型范围
通过条件判断缩小f0的类型范围,让TypeScript在每个分支中确定具体的类型:
// 保留原类型和变量定义... const f0 = f[0]; if (f0.ftype === "ip") { console.log(c[f0.ftype](f0.value)); // 分支内类型为Filter<"ip">,校验通过 } else { console.log(c[f0.ftype](f0.value)); // 分支内类型为Filter<"magic">,校验通过 }
方案3:遍历数组时直接处理(推荐)
如果需要处理整个数组,直接在遍历逻辑中使用,TypeScript会自动推断每个元素的具体类型:
// 保留原类型和变量定义... f.forEach(filter => { console.log(c[filter.ftype](filter.value)); // 遍历过程中自动识别每个元素的具体类型,校验通过 });
内容的提问来源于stack exchange,提问作者Liad
相关产品推荐
相关产品推荐

