TypeScript绑定函数丢失重载问题求助
TypeScript绑定重载函数后仅识别最后一个重载的问题
问题场景
带有重载声明的函数,直接调用时TypeScript能正常识别所有重载签名,但通过bind绑定前置参数返回新函数后,调用新函数时只会识别最后一个重载,导致类型校验报错。示例代码如下:
function fn(arg1: any, arg2: { id: number }): void function fn(arg1: any, arg2: { value: string }): void function fn(arg1: any, arg2: { id: number } | { value: string }) { } function useFn() { const arg1 = 'some predefined arg' return fn.bind(null, arg1) } const myFn = useFn() myFn({ id: 3 }) // 报错:Argument of type '{ id: number; }' is not assignable to parameter of type '{ value: string; }'
问题原因
这不是TypeScript服务临时异常,而是TypeScript的类型推断机制限制:当对重载函数调用bind时,TypeScript只会基于重载列表的最后一个签名(也就是实现前的那个重载)来推导绑定后的函数类型,不会保留所有重载信息。
解决方案
1. 手动指定返回函数的重载类型
先定义对应重载的类型别名,再通过类型断言告诉TypeScript绑定后的函数符合该类型:
// 定义重载函数的类型 type BoundFn = { (arg2: { id: number }): void (arg2: { value: string }): void } function fn(arg1: any, arg2: { id: number }): void function fn(arg1: any, arg2: { value: string }): void function fn(arg1: any, arg2: { id: number } | { value: string }) { } function useFn(): BoundFn { const arg1 = 'some predefined arg' // 用类型断言指定返回类型 return fn.bind(null, arg1) as BoundFn } const myFn = useFn() myFn({ id: 3 }) // 正常通过校验 myFn({ value: "test" }) // 正常通过校验
2. 用箭头函数封装替代bind
避免直接使用bind,改用箭头函数手动绑定参数,TypeScript能正确继承原函数的重载推断:
function fn(arg1: any, arg2: { id: number }): void function fn(arg1: any, arg2: { value: string }): void function fn(arg1: any, arg2: { id: number } | { value: string }) { } function useFn() { const arg1 = 'some predefined arg' // 箭头函数封装,自动继承原函数参数类型 return (arg2) => fn(arg1, arg2) } const myFn = useFn() myFn({ id: 3 }) // 正常通过校验 myFn({ value: "test" }) // 正常通过校验
3. 给useFn添加重载声明
如果需要更精准的重载支持,可以给返回绑定函数的useFn也添加重载签名:
function fn(arg1: any, arg2: { id: number }): void function fn(arg1: any, arg2: { value: string }): void function fn(arg1: any, arg2: { id: number } | { value: string }) { } // 给useFn添加重载声明 function useFn(): (arg2: { id: number }) => void function useFn(): (arg2: { value: string }) => void function useFn() { const arg1 = 'some predefined arg' return fn.bind(null, arg1) } const myFn = useFn() myFn({ id: 3 }) // 正常通过校验
内容的提问来源于stack exchange,提问作者drdv
相关产品推荐
相关产品推荐

