TypeScript函数重载报TS2394:重载签名与实现签名不兼容
问题原因
TS2394 报错的核心原因是实现签名不符合TypeScript函数重载的校验规则:所有对外暴露的重载调用签名,必须能被最终的实现签名兼容。你的代码存在两处不匹配:
- 实现签名仅声明了泛型参数
<D>,但前三个重载签名用到了独立泛型T,实现签名的泛型列表没有覆盖所有重载用到的泛型类型 - 实现签名的参数类型没有覆盖所有重载的入参组合:第二个参数位置既可能是任意类型的消息体,也可能是回调函数,第三个参数是可选的回调,当前实现签名的参数定义没有覆盖这些可能性。
修复方案
调整实现签名的泛型定义和参数类型,让它兼容所有重载的调用场景,原有重载签名不需要改动:
type Callback<TReturn = unknown, TArgs extends any[] = []> = (...args: TArgs) => TReturn; class YourClass { // 原有重载签名保持不变 public fireEvent(eventName: string): void; public fireEvent<T>(eventName: string, messageDTO: T): void; public fireEvent<T, D>(eventName: string, messageDTO: T, dataCallback: Callback<void, [D]>): void; public fireEvent<D>(eventName: string, dataCallback: Callback<void, [D]>): void; // 修正后的实现签名 public fireEvent<T = never, D = never>( eventName: string, arg2?: T | Callback<void, [D]>, arg3?: Callback<void, [D]> ): void { // 函数内部通过类型守卫区分不同调用场景即可 if (typeof arg2 === 'function') { // 匹配 fireEvent(eventName, dataCallback) 场景 const callback = arg2; // 编写对应逻辑 return; } if (typeof arg3 === 'function') { // 匹配 fireEvent(eventName, messageDTO, dataCallback) 场景 const message = arg2 as T; const callback = arg3; // 编写对应逻辑 return; } if (arg2 !== undefined) { // 匹配 fireEvent(eventName, messageDTO) 场景 const message = arg2 as T; // 编写对应逻辑 return; } // 匹配 fireEvent(eventName) 场景 // 编写对应逻辑 } }
注意事项
- 实现签名的泛型列表需要覆盖所有重载签名用到的泛型参数,给泛型设置默认值可以避免内部类型校验报错
- 实现签名里,非首个必选参数都要标记为可选,类型要对应该位置所有可能出现的参数类型的联合类型
- 函数内部通过类型守卫区分不同入参组合,获得正确的类型提示后再编写业务逻辑
内容的提问来源于stack exchange,提问作者Muhammad Waqar
相关产品推荐
相关产品推荐

