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

如何用TypeScript禁止继承抽象类的子类实现构造函数?

禁止TypeScript抽象类子类自定义构造函数的实现方案

你定义了抽象类Foo,希望子类继承时不能自定义构造函数,但private构造函数会完全禁止继承,protected构造函数又允许子类编写自己的构造函数。可以通过以下方式实现需求:

核心思路是给抽象类的构造函数添加一个仅父类能访问的私有参数,让子类无法合法调用super(),从而阻止子类自定义构造函数。

abstract class Foo {
  // 定义仅父类可访问的私有符号,作为构造函数的必填参数
  private static readonly ConstructorToken = Symbol('FooConstructorToken');

  protected constructor(token: typeof Foo.ConstructorToken) {
    if (token !== Foo.ConstructorToken) {
      throw new Error('禁止直接实例化或非法调用构造函数');
    }
    // 父类构造逻辑
    console.log('Foo构造函数执行');
  }

  // 提供protected静态方法,让子类可以安全创建实例
  protected static createInstance<T extends Foo>(this: new (token: typeof Foo.ConstructorToken) => T): T {
    return new this(Foo.ConstructorToken);
  }
}

// 正确示例:子类不自定义构造函数,通过静态方法创建实例
class Bar extends Foo {
  static create(): Bar {
    return super.createInstance();
  }

  // 子类的其他方法
  sayHi() {
    console.log('Bar says hi');
  }
}

// 错误示例:子类自定义构造函数会编译报错
class Baz extends Foo {
  constructor() {
    // 编译错误:无法访问Foo的私有属性ConstructorToken
    super(Foo.ConstructorToken);
  }
}

// 测试正确的子类
const bar = Bar.create();
bar.sayHi(); // 输出:Bar says hi

方案说明

  • 抽象类Foo的构造函数需要一个私有符号作为参数,这个符号仅Foo内部可访问,子类无法获取。
  • 子类如果自定义构造函数,必须调用super()但无法传入合法参数,直接触发编译错误,彻底禁止自定义构造函数的行为。
  • 子类通过继承Foo的createInstance静态方法来创建实例,既保证了实例化的合法性,也符合抽象类的设计初衷。
  • 外部无法直接实例化Foo或其子类,必须通过子类提供的静态方法完成实例创建。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 18:06:06