如何要求方法参数泛型中包含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
相关产品推荐
相关产品推荐

