You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让TypeScript自动推断泛型函数参数的重载类型?

TypeScript重载函数的类型推断问题

问题描述

我实现了一个awaitCallback函数,它的第一个参数是以回调函数作为最后一个入参的目标函数,后续传入的参数则是该目标函数(func)除回调外的所有入参。这个函数的设计目的是返回一个Promise,Promise的结果由目标函数的回调内部解析,因此调用时无需传入回调参数。

这个实现处理非重载函数时表现正常,但面对重载函数时存在类型推断问题。理想情况下,TypeScript应该能根据传入的args自动匹配func对应的正确重载。如果显式指定awaitCallback的类型参数,类型推断就能正常工作。但我想知道:TypeScript能否通过Args参数自动选择满足约束的函数重载?

代码实现

type NodeCallback<R> = (err: (Error | null) | R, matches?: R | undefined) => void;

type Func<Args extends unknown[], LA, R> = (...args: [...Args, LA]) => R;

export function awaitCallback<Args extends unknown[], LA>(func: Func<Args, NodeCallback<LA>, void>, ...args: Args): Promise<LA> {
    return new Promise((resolve, reject) => {
        const callback: NodeCallback<LA> = (err, result) => {
            if (result !== undefined)
                resolve(result);
            else if (err instanceof Error)
                reject(err);
            else if (err !== null)
                resolve(err);
            else
                reject(new Error('Unknown error'));
        };

        func(...args, callback);
    });
};

declare function test(arg1: string, arg2: number, callback: (err: Error | null, matches: string[]) => void): void;

declare function test2(arg1: string, callback: (err: Error | null, matches: string[]) => void): void;
declare function test2(arg1: string, arg2: number | undefined, callback: (err: Error | null, matches: number[]) => void): void;

// 无重载函数:类型推断正常
const res = awaitCallback(test, 'test', 3);
//    ^?

// 显式指定类型参数:正常工作
const res2 = awaitCallback<[string], string[]>(test2, 'test');
//    ^?

// 自动推断无法匹配宽松重载:类型错误
const res3 = awaitCallback(test2, 'test');
//    ^?

// 匹配最具体的重载:类型推断正常
const res4 = awaitCallback(test2, 'test', 3);
//    ^?

当前问题表现

  • 无重载的test函数:调用awaitCallback时能正确推断返回类型为Promise<string[]>
  • 显式指定类型参数调用test2:返回类型正确推断为Promise<string[]>
  • 仅传入'test'调用test2:TypeScript无法自动匹配对应的重载,返回类型推断为Promise<never>,不符合预期
  • 传入'test'和3调用test2:能正确匹配最具体的重载,返回类型推断为Promise<number[]>

内容的提问来源于stack exchange,提问作者thomasrea0113

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 05:07:32