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

TypeScript接口映射时如何保留函数重载?

如何为带函数重载的接口生成异步版本?

假设有一个包含函数重载的接口:

interface Api {
  parseNumber(input: string, useBigInt: true): bigint
  parseNumber(input: string, useBigInt: false): number
}

需要生成一个新接口,其中每个函数都变为异步版本,返回值包裹在Promise中,目标接口如下:

{
  parseNumber(input: string, useBigInt: true): Promise<bigint>
  parseNumber(input: string, useBigInt: false): Promise<number>
}

已尝试方案的问题

直接通过映射类型处理时,会丢失除最后一个以外的所有函数重载:

type TMethodNames = keyof Api; // 正确:`parseNumber`
type TMethodImplementations = Api[keyof Api]; // 正确:包含两个签名
type TMethodReturns = ReturnType<TMethodImplementations> // 错误:仅得到`number`而非`number | bigint`

type AsyncApi = {
  [TMethodName in keyof Api]: (...args: Parameters<Api[TMethodName]>) => Promise<ReturnType<Api[TMethodName]>>
};

const asyncApi = null as unknown as AsyncApi;
asyncApi.parseNumber('123', false); // 正确:返回类型为`Promise<number>`
asyncApi.parseNumber('123', true); // 错误:该签名完全丢失

解决方案

通过定义一个工具类型,将每个函数重载单独转换为异步版本,再利用TypeScript对交集类型的处理保留所有重载:

// 工具类型:将单个函数转换为异步版本
type Asyncify<T> = T extends (...args: infer Args) => infer Return 
  ? (...args: Args) => Promise<Return> 
  : never;

// 生成异步版本接口
type AsyncApi = {
  [K in keyof Api]: Asyncify<Api[K]>;
};

// 测试验证
const asyncApi = null as unknown as AsyncApi;
asyncApi.parseNumber('123', false); // 返回 Promise<number>
asyncApi.parseNumber('123', true); // 返回 Promise<bigint>

原理:TypeScript中,函数重载会被表示为多个函数类型的交集。Asyncify工具类型会对交集中的每个函数类型单独处理,将其转换为异步版本,最终结果依然是多个异步函数的交集,从而完整保留所有重载签名。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 08:12:33