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

如何为TypeScript Promise设置拒绝值类型?

Enforcing Type Safety for Promise Rejection Values in TypeScript

Great question! By default, TypeScript's Promise<T> only explicitly types the resolved value—rejected values are treated as unknown (or any in older versions), which leaves you without compile-time checks for what gets passed to reject(). Let's fix that with two key steps: restricting what can be passed to reject when creating the Promise, and ensuring type safety when handling rejections.

Step 1: Create a Typed Promise Factory Function

To enforce that reject() only accepts your desired type (in this case, number), we'll wrap the native Promise constructor in a generic factory function that explicitly types both resolve and reject parameters:

// Factory function to create Promises with typed resolve/reject
function createTypedPromise<TResolve, TReject>(
  executor: (
    resolve: (value: TResolve) => void,
    reject: (reason: TReject) => void
  ) => void
): Promise<TResolve> {
  return new Promise(executor);
}

Now rewrite your start function using this factory. Notice how we specify <string, number> to set the resolved type as string and rejected type as number:

const someCondition = false; // Example condition

const start = (): Promise<string> => {
  return createTypedPromise<string, number>((resolve, reject) => {
    if (someCondition) {
      resolve('correct!');
    } else {
      reject(-1); // ✅ Valid: passes a number
      // reject('oops'); // ❌ Compile error: Argument of type 'string' is not assignable to type 'number'
    }
  });
};

This immediately prevents invalid values from being passed to reject() during development.

Step 2: Enforce Type Safety When Handling Rejections

Even with the factory function, TypeScript still infers rejection values as unknown in .catch() by default. To get compile-time checks here, you have two solid options:

Option A: Use a Type Guard

This is the safest approach because it validates the type at runtime too:

start()
  .then((result) => console.log('Success:', result))
  .catch((err) => {
    if (typeof err === 'number') {
      // ✅ err is typed as number here
      console.log('Error code:', err);
    } else {
      // Handle unexpected types (though our factory makes this unlikely)
      throw new Error(`Unexpected rejection type: ${typeof err}`);
    }
  });

Option B: Explicitly Type the Catch Parameter

If you're confident that the rejection will always be a number (thanks to our factory function), you can explicitly type the catch parameter. This will throw a compile error if you try to treat it as the wrong type:

start()
  .then((result) => console.log('Success:', result))
  .catch((err: number) => {
    // ✅ err is enforced as number; trying to call string methods here will throw a compile error
    console.log('Error code:', err);
    // err.toUpperCase(); // ❌ Compile error: Property 'toUpperCase' does not exist on type 'number'
  });

Why This Works

TypeScript's native Promise type doesn't include rejection typing because the ECMAScript Promise spec allows rejecting with any value. Our factory function adds a layer of compile-time safety by restricting what the executor can pass to reject(), and the catch handling ensures you can't accidentally misuse the rejection type.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:15:27