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

TypeScript中基于工厂函数的工厂类与单例工厂类继承实现问题咨询

解决SingletonFactory继承Factory的TypeScript错误问题

你的核心需求是实现一个继承自Factory的单例工厂类,问题出在对TypeScript中类的方法与实例属性的访问规则理解上。我来一步步拆解问题,然后给出可行的解决方案:

为什么你的代码会报错?

第一个版本的错误原因

在最初的代码里,Factory类的make是一个实例属性(类型为函数),而不是类的原型方法。当你在SingletonFactory里尝试用super.make()调用父类的逻辑时,TypeScript的规则是:super关键字只能用来访问父类的原型方法(public/protected),无法直接访问父类的实例属性,所以会抛出Only public and protected methods of the base class are accessible via the 'super' keyword的错误。

第二个版本的错误原因

你尝试把make声明成方法,但又在构造函数里给this.make赋值,这就造成了冲突:TypeScript认为你要么定义一个方法(需要有实现体),要么定义一个实例属性,但不能同时声明方法的签名又给实例属性赋值,于是报错Function implementation is missing or not immediately following the declaration。

正确的实现方案

方案一:将make定义为类的原型方法

这是最符合面向对象设计的方案,把创建逻辑封装在父类的方法中,子类通过super.make()调用父类的创建逻辑:

type FactoryFunction<T> = () => T;

export class Factory<T> {
    // 把传入的工厂函数存在私有属性中
    private readonly factory: FactoryFunction<T>;

    constructor(factory: FactoryFunction<T>) {
        this.factory = factory;
    }

    // 定义为类的public方法,子类可以通过super访问
    public make(): T {
        return this.factory();
    }
}

export class SingletonFactory<T> extends Factory<T> {
    // 用可选类型避免初始化时的赋值问题
    private instance?: T;

    constructor(factory: FactoryFunction<T>) {
        super(factory);
    }

    // 使用override关键字明确重写父类方法(TypeScript 4.3+支持)
    public override make(): T {
        if (!this.instance) {
            // 现在可以正确调用父类的make方法创建实例
            this.instance = super.make();
        }
        return this.instance;
    }
}

方案二:封装受保护的创建方法(保留实例属性风格)

如果你更倾向于把make作为实例属性(比如用箭头函数绑定this),可以把核心的创建逻辑封装成父类的protected方法,子类直接调用这个方法:

type FactoryFunction<T> = () => T;

export class Factory<T> {
    private readonly factory: FactoryFunction<T>;

    constructor(factory: FactoryFunction<T>) {
        this.factory = factory;
    }

    // 受保护的方法,子类可以访问
    protected createInstance(): T {
        return this.factory();
    }

    // make作为实例属性
    public make = (): T => {
        return this.createInstance();
    };
}

export class SingletonFactory<T> extends Factory<T> {
    private instance?: T;

    constructor(factory: FactoryFunction<T>) {
        super(factory);
    }

    // 重写make属性
    public override make = (): T => {
        if (!this.instance) {
            // 调用父类的受保护方法创建实例
            this.instance = this.createInstance();
        }
        return this.instance;
    };
}

验证使用方式

两种方案都可以正常使用,比如:

// 创建一个普通工厂
const normalFactory = new Factory(() => ({ id: Math.random() }));
console.log(normalFactory.make() !== normalFactory.make()); // true,每次创建新实例

// 创建单例工厂
const singletonFactory = new SingletonFactory(() => ({ id: Math.random() }));
console.log(singletonFactory.make() === singletonFactory.make()); // true,始终返回同一个实例

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 05:23:17