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

TypeScript提取Promise泛型并返回[Error,T]元组类型实现方案

问题场景

我编写了一个接收Promise<T>类型入参的函数,目前它的返回值类型为Promise<(null | any)[] | (any | null)[]>,希望将其返回类型修改为Promise<[Error, T]>。

初始实现代码:

// ↓ 希望在这里传入提取到的Promise resolve类型
const customAsyncAwait = <T extends Promise<any>>(promise: T) => {
  return promise
    .then(res => [null, res])
    .catch(error => [error, null]);
}

函数调用方式如下:

async function init() {
  const api = axios.get<Plants[]>('<API_NAME>'); // typeof api =  Promise<AxiosResponse<Plants[], any>>
  const [error, data] = await customAsyncAwait(api); // 目前typeof data = any,期望类型为AxiosResponse<Plants[], any>
}

更新

我目前已经实现了符合类型要求的版本,但写法较为冗余,想知道是否有更简洁优雅的实现方式:

const customAsyncAwait = <T>(promise: Promise<T>): Promise<[Error, T]> => {
  const result: [Error, T] = [null, null];

  return promise
    .then((res) => {
      result[0] = null;
      result[1] = res;
      return result;
    })
    .catch((error: Error) => {
      result[0] = error;
      result[1] = null;
      return result;
    });
}
简洁实现方案

不需要提前声明result变量,使用as const做常量断言就可以让TS自动识别数组为元组类型,写法非常简洁:

const customAsyncAwait = <T>(promise: Promise<T>) => {
  return promise
    .then(res => [null, res] as const)
    .catch(err => [err, null] as const) as Promise<[Error | null, T | null]>;
}
  • 这里把返回类型标注为Promise<[Error | null, T | null]>比Promise<[Error, T]>更严谨:成功状态下error固定为null,失败状态下data固定为null,完全符合实际运行逻辑,不会出现类型提示和实际值不符的问题。
  • 调用该函数时TS会自动推导泛型T的类型,不需要手动传入,data的类型会和传入Promise的resolve值类型完全一致,符合使用预期。

如果一定要严格匹配预期的Promise<[Error, T]>返回类型,只需要替换最后断言的类型即可:

const customAsyncAwait = <T>(promise: Promise<T>) => {
  return promise
    .then(res => [null, res] as const)
    .catch(err => [err, null] as const) as Promise<[Error, T]>;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 17:15:44