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

TypeScript中如何为函数返回的Promise定义reject类型?

在TypeScript中标注Promise的Reject类型

TypeScript原生不支持通过Promise<>泛型参数直接定义reject的类型——Promise<T>中的T仅代表resolve时的返回值类型,reject的类型默认被推断为any,无法在函数返回类型中直接体现。

不过,针对你想要明确标注reject类型、让IDE感知并提示未处理拒绝的需求,可以通过以下几种方案实现:

1. 使用JSDoc的@throws注解(最实用)

TypeScript兼容JSDoc语法,你可以通过@throws注解明确说明Promise reject时抛出的错误类型。主流IDE(如VS Code)会识别该注解,在调用函数时给出提示,效果类似PHP的@throws。

示例代码:

interface ValidationError {
  code: number;
  message: string;
}

/**
 * 验证JSON格式有效性
 * @param json 待验证的JSON对象
 * @returns Promise:验证成功时resolve空值;失败时reject ValidationError对象
 * @throws {ValidationError} 当JSON不符合规则时触发Promise拒绝
 */
function validate(json: unknown): Promise<void> {
  return new Promise((resolve, reject) => {
    // 模拟验证逻辑
    if (typeof json !== 'object' || json === null) {
      reject({ code: 400, message: 'JSON必须是非空对象' } as ValidationError);
      return;
    }
    resolve();
  });
}

调用该函数时,IDE会提示你可能需要处理ValidationError类型的拒绝,若未添加catch或try/catch(使用await时),部分IDE会给出警告。

2. 自定义带Reject类型的Promise类型(类型层面辅助)

你可以创建一个自定义泛型类型,显式声明resolve和reject的类型。这只是类型层面的标注,不会改变运行时行为,但能让开发者在编写代码时直观感知reject的类型:

// 自定义类型,同时声明resolve和reject的类型
type PromiseWithReject<ResolveType, RejectType> = Promise<ResolveType> & {
  // 仅用于类型提示,无实际运行时作用
  __rejectType?: RejectType;
};

interface ValidationError {
  code: number;
  message: string;
}

function validate(json: unknown): PromiseWithReject<void, ValidationError> {
  return new Promise((resolve, reject) => {
    // 验证逻辑同上
    if (typeof json !== 'object' || json === null) {
      reject({ code: 400, message: 'JSON必须是非空对象' } as ValidationError);
      return;
    }
    resolve();
  }) as PromiseWithReject<void, ValidationError>;
}

当你查看函数返回类型时,能直接看到reject对应的ValidationError类型,帮助团队成员明确函数的错误场景。

3. 使用Either类型替代Promise(更严谨的类型约束)

如果你希望完全通过类型系统约束成功/失败的结果,可以放弃原生Promise,改用Either类型(可自行实现):

type Either<Left, Right> = { type: 'left'; value: Left } | { type: 'right'; value: Right };

interface ValidationError {
  code: number;
  message: string;
}

async function validate(json: unknown): Promise<Either<ValidationError, void>> {
  if (typeof json !== 'object' || json === null) {
    return { type: 'left', value: { code: 400, message: 'JSON必须是非空对象' } };
  }
  return { type: 'right', value: undefined };
}

// 调用时必须显式处理两种情况
const result = await validate({});
if (result.type === 'left') {
  // 处理ValidationError
  console.error(result.value.message);
} else {
  // 处理成功逻辑
}

这种方式强制开发者处理成功和失败的分支,完全避免了未处理的reject问题,但需要改变函数的返回形式,适合对类型严谨性要求较高的场景。

与Stack Overflow问题的区别

你提到的Stack Overflow问题主要聚焦于如何在catch块中推断reject的类型,而你的需求是在函数返回类型中直接标注reject的类型——上述方案更贴合你的核心诉求,重点放在让函数的类型签名清晰传达错误信息,而非仅在捕获时推断类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 15:10:16