在TypeScript中创建通用代理函数出现类型不匹配如何解决
这个需求完全可以在TypeScript中实现,原代码编译报错主要由语法错误、泛型条件类型的TS推断限制两类问题导致,修复方案如下:
完整修复代码
type Callback<F extends (...args: any) => any> = F extends (...args: infer P) => infer R ? P extends [] ? (onComplete?: (result: R) => void) => void : (parameters: P, onComplete?: (result: R) => void) => void : never; function createCallback<F extends (...args: any[]) => any>(func: F): Callback<F> { return ((parameters?: Parameters<F> | ((result: ReturnType<F>) => void), onComplete?: (result: ReturnType<F>) => void): void => { // 无参数调用场景 if (!parameters && !onComplete) { func(); return; } if (Array.isArray(parameters)) { const result = func(...parameters); if (onComplete) { onComplete(result); } } else if (typeof parameters === "function") { const result = func(); parameters(result); } }) as unknown as Callback<F>; }
核心修复说明
- 修正语法错误:原代码中
R result = xxx是非法的TS变量声明写法,修改后直接利用TS类型推导自动识别返回值类型即可 - 补充边界分支:新增无任何参数的调用逻辑,适配无参数函数不需要传回调的使用场景
- 兼容TS类型推断限制:由于
Callback<F>是依赖泛型F的条件类型,在F未被具体传入函数类型替换前,TS无法判断返回函数是否匹配类型定义,因此通过as unknown as Callback<F>做类型断言,该断言完全安全,因为实现逻辑和类型定义的要求完全一致 - 简化泛型定义:直接使用TS内置的
Parameters和ReturnType工具类型提取传入函数的参数、返回值类型,减少冗余泛型声明
效果验证
// 测试无参数函数 const fnNoArgs = () => "无参数函数返回值"; const wrappedNoArgs = createCallback(fnNoArgs); // 调用方式完全符合预期 wrappedNoArgs(); // 合法 wrappedNoArgs((res) => console.log(res)); // 合法 // 测试有参数函数 const fnHasArgs = (id: number, name: string) => `用户ID:${id}, 用户名:${name}`; const wrappedHasArgs = createCallback(fnHasArgs); // 调用方式完全符合预期 wrappedHasArgs([1, "张三"]); // 合法 wrappedHasArgs([1, "张三"], (res) => console.log(res)); // 合法 // 不符合要求的调用会被TS拦截:wrappedHasArgs((res) => console.log(res)) // 类型报错
内容的提问来源于stack exchange,提问作者Dmitry
相关产品推荐
相关产品推荐

