如何修正TypeScript中foo函数的回调返回类型推导问题?
解决TypeScript回调函数类型推导不匹配问题
原代码中,foo函数的泛型R被TypeScript推断为(string | number)[],因为回调函数的泛型参数S被解析为string | number的联合类型,导致返回的str和num都继承了这个联合类型数组,与实际返回的string[]和number[]不匹配。
要修复这个问题,需要让TypeScript分别处理回调函数传入string和number时的返回类型,具体修改如下:
// 定义工具类型,提取回调函数对应输入类型的返回值 type StringReturn<F> = F extends (s: string) => infer R ? R : never; type NumberReturn<F> = F extends (s: number) => infer R ? R : never; function foo<CB extends <S extends string | number>(s: S) => unknown>(cb: CB) { return { str: cb("one") as StringReturn<CB>, num: cb(1) as NumberReturn<CB>, }; } // 现在result的类型为 { str: string[], num: number[] },符合预期 const result = foo((s) => [s]);
说明:
- 工具类型
StringReturn和NumberReturn通过条件类型infer,分别提取回调函数在接收string和number参数时的返回类型。 - 修改
foo的泛型为CB,表示回调函数的类型,确保它是一个能接收string或number的泛型函数。 - 通过类型断言,将
cb("one")和cb(1)分别指定为对应的返回类型,让TypeScript正确推导结果类型。
如果需要更简洁的写法,也可以直接在返回类型中使用条件类型,无需额外工具类型:
function foo<CB extends <S extends string | number>(s: S) => unknown>(cb: CB) { return { str: cb("one") as (CB extends (s: string) => infer R ? R : never), num: cb(1) as (CB extends (s: number) => infer R ? R : never), }; }
内容的提问来源于stack exchange,提问作者aiven715
相关产品推荐
相关产品推荐

