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

为何Promise<A | B>无法赋值给Promise<A> | Promise<B>?

TypeScript中Promise联合类型的赋值兼容性问题
type A = Promise<string> | Promise<number>
type B = Promise<string | number>

const a: A = Math.random() > 0.5 ? Promise.resolve('string') : Promise.resolve(1)
const b: B = Promise.resolve(Math.random() > 0.5 ? 'string' : 1)

class C {
  fa(a: A) {
    console.log(a)
  }

  fb(b: B) {
    console.log(b)
  }
}
const c = new C()

c.fa(a)
c.fb(b)

c.fa(b) /* <-- 此处报错:
Argument of type 'B' is not assignable to parameter of type 'A'.
  Type 'Promise<string | number>' is not assignable to type 'Promise<string>'.
    Type 'string | number' is not assignable to type 'string'.
      Type 'number' is not assignable to type 'string'.ts(2345)
*/
c.fb(a) // 此处可正常运行

问题

为什么代码中c.fa(b)会出现类型赋值错误,而c.fb(a)可正常执行?

解答

核心差异在于A和B两个类型的本质:

  • A是两个明确Promise类型的联合:它代表的是一个二选一的Promise——要么是只能resolve字符串的Promise<string>,要么是只能resolve数字的Promise<number>,二者必居其一。
  • B是单个Promise包裹着联合类型:它是一个不确定的Promise,最终resolve的值可能是字符串,也可能是数字,无法提前确定具体类型。

1. 为什么c.fb(a)可以正常执行?

a的类型是A,也就是要么是Promise<string>,要么是Promise<number>。TypeScript中Promise的泛型是协变的:如果泛型参数X是Y的子类型,那么Promise<X>可以赋值给Promise<Y>。

  • string是string | number的子类型,所以Promise<string>能赋值给Promise<string | number>;
  • number也是string | number的子类型,所以Promise<number>也能赋值给Promise<string | number>。
    既然A的两个分支都兼容B,那整个A类型自然可以传递给fb方法的参数。

2. 为什么c.fa(b)会报错?

b的类型是B,也就是Promise<string | number>。而fa方法要求的参数是A——要么是纯字符串Promise,要么是纯数字Promise。但b这个Promise既可能返回字符串,也可能返回数字,它既不符合Promise<string>的要求(因为存在返回数字的可能),也不符合Promise<number>的要求(因为存在返回字符串的可能),所以无法赋值给A类型,TypeScript就会抛出类型不兼容的错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 21:20:25