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

TypeScript能否通过this类型校验禁止方法传入自身实例作为参数

问题解答

首先明确:你要的「允许同类型其他实例传入、仅禁止当前实例自身传入」的校验,无法仅通过TypeScript静态类型系统实现,原因如下:

  • TypeScript是结构化类型系统,不会追踪单个实例的唯一身份,同一个类实例化出来的所有对象,都共享同一个类型,比如你示例中的b和bb的类型都是B,静态层面无法区分二者。
  • 你示例中的T extends this ? never : T写法的逻辑是基于类型匹配的,只要传入的参数类型和当前实例类型一致,就会被判定为never,会把b.addChild(bb)也误判为错误,不符合你的预期。

如果你可以接受「禁止传入所有和当前实例同类型的实例」的校验规则,可以调整写法实现前两个测试用例的校验效果:

type AB = A | B;
export class A {
    a: string = '';
}
export class B {
    b: string = '';

    /** 仅允许传入A类实例,禁止传入所有B类实例 */
    addChild<T extends AB>(token: Exclude<T, B>) {
        return this;
    }
}

const a = new A();
const b = new B();

b.addChild(a); // 🟢 正常通过
b.addChild(b); // 🔴 抛出类型错误

如果你必须要保留「允许同类型其他实例传入」的规则,只能搭配运行时校验实现,代码如下:

type AB = A | B;
export class A {
    a: string = '';
}
export class B {
    b: string = '';

    addChild(token: AB) {
        if (token === this) {
            throw new Error('禁止传入实例自身作为子节点');
        }
        return this;
    }
}

const a = new A();
const b = new B();
const bb = new B();

b.addChild(a); // 🟢 正常通过
b.addChild(bb); // 🟢 正常通过
b.addChild(b); // 🔴 运行时抛出错误

该代码在传入自身实例时会主动抛出运行时错误,同时静态层面允许所有符合AB类型的参数传入,满足你b.addChild(bb)正常通过的需求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 12:48:04