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

TypeScript中如何动态推导回调转Promise包装函数的泛型类型

实现方案

1. 定义类型工具与包装函数

// 从配置项中提取success回调的入参类型
type ExtractSuccessRes<T> = T extends { success?: (res: infer R) => any } ? R : never;
// 从配置项中提取fail回调的入参类型
type ExtractFailRes<T> = T extends { fail?: (res: infer R) => any } ? R : never;

function toAsync<OptType>(fn: (opt: OptType) => any) {
  return async (
    // 若不需要支持用户传入自定义success/fail/complete,可将OptType替换为Omit<OptType, 'success'|'fail'|'complete'>
    opt: OptType
  ): Promise<ExtractSuccessRes<OptType>> => {
    return new Promise<ExtractSuccessRes<OptType>>((resolve, reject) => {
      fn({
        ...(opt || {}),
        success: (res: ExtractSuccessRes<OptType>) => {
          // 若需要保留用户自定义的success回调逻辑,可保留下行
          opt?.success?.(res);
          resolve(res);
        },
        fail: (res: ExtractFailRes<OptType>) => {
          // 若需要保留用户自定义的fail回调逻辑,可保留下行
          opt?.fail?.(res);
          reject(res);
        },
        complete: (res: any) => {
          // 若需要保留用户自定义的complete回调逻辑,可保留下行
          opt?.complete?.(res);
        }
      } as unknown as OptType);
    });
  };
}

2. 使用示例

// 示例待包装函数类型定义
type RequestFailResType = { code: number; msg: string };
type RequestSuccessResType = { data: any; status: number };
type RequestCompleteResType = { type: 'success' | 'fail' };
function request(opt:{
    fail?:(res:RequestFailResType)=>any;
    success?:(res:RequestSuccessResType)=>any;
    complete?:(res:RequestCompleteResType)=>any;
    url:string
}):any{
    // 原有业务逻辑
}

// 直接调用包装函数,无需手动传入泛型
const asyncRequest = toAsync(request);
// 自动推导类型为:asyncRequest (opt: { url:string, fail?:..., success?:..., complete?:... }) => Promise<RequestSuccessResType>

// 调用时自动提示入参字段,返回值自动识别类型
asyncRequest({ url: '/api/test' })
  .then(res => { /* res 自动识别为 RequestSuccessResType 类型 */ })
  .catch(err => { /* err 自动识别为 RequestFailResType 类型 */ })

核心逻辑说明

  • 仅需声明1个泛型参数OptType,TS会自动从传入的待包装函数入参中推导该类型,无需手动传入
  • 通过TS条件类型的infer语法,直接从OptType中反向提取success、fail回调的入参类型,无需额外手动声明类型
  • 可根据业务需求选择是否保留用户传入的自定义回调逻辑,类型推导不受影响

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 14:39:05