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

如何要求方法参数泛型中包含this类型(TypeScript)

解决方案

要实现from方法,让源元素的允许目标类型包含当前实例,我们需要通过条件类型反向约束参数类型,而非直接限定Element<this>。

修改后的Element抽象类

// 工具类型:筛选出允许连接到当前元素T的源元素类型
type SourceFor<T extends Element<any>> = 
  Element<any> extends infer S 
    ? T extends S['Target'] 
      ? S 
      : never 
    : never;

abstract class Element<Target = unknown> {
  targets: Target[] = [];

  into(...targets: Target[]): this {
    targets.forEach(target => this.targets.push(target));
    return this;
  }

  from(...sources: SourceFor<this>[]): this {
    sources.forEach(source => source.into(this));
    return this;
  }
}

测试验证

沿用你提供的子类示例,现在所有预期场景都能正常工作:

class First extends Element<First | Second> {
  firstProp = "";
}
class Second extends Element<First | Second> {
  secondProp = "";
}
class Third extends Element<Third> {
  thirdProp = "";
}

const first = new First();
const second = new Second();
const third = new Third();

first.from(second); // ✅ 正常工作(Second允许连接First)
first.from(first); // ✅ 正常工作(First允许连接自身)
first.from(third); // ❌ 报错(Third仅允许连接自身,不包含First)
second.from(first); // ✅ 正常工作(First允许连接Second)
third.from(third); // ✅ 正常工作
third.from(first); // ❌ 报错

原理说明

  • 核心是SourceFor<T>工具类型:它遍历所有Element子类,判断当前元素T是否属于该子类的允许目标类型S['Target'],如果是则保留该子类类型,否则返回never(会被TypeScript视为无效参数)。
  • 之前的错误实现from(...sources: Element<this>): this要求源元素的允许目标类型严格等于当前实例类型,但实际我们需要的是包含关系,因此必须用条件类型反向校验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 03:01:24