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

TypeScript中Promise.all无法处理联合类型的技术咨询

Why does combining union function types with Promise.all throw a TypeScript error?

Let’s break down what’s happening here, and how to fix it without ditching your union type.

The Problem Explained

Your Promisable type is a union of two async functions: one returns Promise<string>, the other Promise<number>. When you call promisable(), TypeScript infers the result as Promise<string> | Promise<number>. Stick that in an array, and you get (Promise<string> | Promise<number>)[].

Here’s the catch: Promise.all expects an iterable of Promises that all resolve to the same (or a unified) type. TypeScript doesn’t automatically convert (Promise<string> | Promise<number>)[] to Iterable<Promise<string | number>>—even though they’re runtime-equivalent, the type system draws a line between "array of either Promise type" and "array of Promises that resolve to a union type". This mismatch is why you get that overload error.

When you remove the union, the array is full of identical Promise<string> values, which fits perfectly with Promise.all’s expected types, so the error goes away.

Fixes That Work With Your Union Type

You don’t have to rewrite your union to () => Promise<string | number>—here are practical alternatives for complex codebases:

1. Explicitly Assert the Array Type

Tell TypeScript to treat the array as Promises resolving to a union type. This is a quick fix that preserves your original union:

type Promisable = (() => Promise<string>) | (() => Promise<number>);
const func = async (promisable: Promisable) => {
  await Promise.all([promisable()] as Array<Promise<string | number>>);
};

2. Use Generics for Type Safety

If your use case allows, refactor Promisable to use a generic. This lets TypeScript infer the exact return type of the passed function, keeping things type-safe while playing nice with Promise.all:

type Promisable<T extends string | number> = () => Promise<T>;
const func = async <T extends string | number>(promisable: Promisable<T>) => {
  await Promise.all([promisable()]);
};

3. Fall Back to unknown (For Looser Type Checks)

If you don’t need strict type checking for the Promise result, assert the Promise to Promise<unknown>. This bypasses the overload mismatch entirely:

type Promisable = (() => Promise<string>) | (() => Promise<number>);
const func = async (promisable: Promisable) => {
  const promise = promisable() as Promise<unknown>;
  await Promise.all([promise]);
};

Wrap-Up

This isn’t a limitation of Promise.all or union types—it’s just TypeScript being strict about distinguishing between arrays of unioned Promises vs. arrays of Promises resolving to a union. The fixes above let you keep your original union function type without rewriting all your complex async signatures.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 23:17:29