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

TypeScript中Promise resolve类型收窄的赋值合法性疑问

TypeScript中Deferred类的resolve赋值合法性解析

先看对应的代码示例:

class Deferred<T> {
  promise: Promise<T>;
  resolve!: (value: T) => void;
  reject!: (reason?: any) => void;

  constructor() {
    this.promise = new Promise<T>((resolve, reject) => {
      this.resolve = resolve;
      this.reject = reject;
    });
  }
}

疑问点

Promise构造器的resolve参数类型是(value: T | PromiseLike<T>) => void,但类中resolve字段的类型仅为(value: T) => void,看似是把接受更宽泛类型的函数赋值给了接受更窄类型的函数,却能通过TypeScript编译,原因是什么?

核心原因:函数参数的逆变特性

TypeScript判断函数类型兼容性时,遵循参数逆变、返回值协变的规则:

  • 返回值协变:若目标函数的返回值类型是源函数返回值类型的子类型,赋值合法。
  • 参数逆变:若源函数的参数类型是目标函数参数类型的超类型(即目标参数类型更具体),赋值合法。

放到这个场景中:

  1. 源函数(Promise构造器的resolve)的参数类型是T | PromiseLike<T>,这是T的超类型(T是T | PromiseLike<T>的子集)。
  2. 目标函数(this.resolve)的参数类型是T,比源函数的参数类型更具体。

根据参数逆变规则,这种赋值完全合法:当外部调用this.resolve时,只能传入T类型的值,而该值完全符合源函数(Promise resolve)的参数要求(T属于T | PromiseLike<T>的范畴),不会出现类型不兼容的问题。

额外说明

这种写法是合理的封装:Deferred类对外暴露的resolve接口只接受T类型,隐藏了Promise原生resolve支持PromiseLike<T>的细节,但内部实现完全兼容,既保证了类型安全,又实现了Deferred的功能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 06:20:44