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

TypeScript:如何在抽象类中实现创建自身实例的逻辑

解决不可变Enemy类hit方法逻辑复用问题

你需要将子类重复的hit逻辑抽至抽象父类,但TypeScript不允许父类直接创建子类实例,以下是三种可行方案:

方案一:抽象工厂方法(推荐,符合开闭原则)

在抽象类中定义一个抽象的实例创建方法,由子类实现自身实例的创建逻辑,父类的hit方法调用该方法完成逻辑复用:

abstract class Enemy {
    abstract readonly attackPower: number;

    constructor(
        public readonly health: number
    ) {
    }

    // 子类需实现该方法,返回自身类型的新实例
    protected abstract create(health: number): this;

    hit(): this {
        return this.create(this.health - 1);
    }
}

class Boss extends Enemy {
    attackPower = 100;

    protected create(health: number): Boss {
        return new Boss(health);
    }
}

class NormalEnemy extends Enemy {
    attackPower = 5;

    protected create(health: number): NormalEnemy {
        return new NormalEnemy(health);
    }
}

该方案扩展性强,新增Enemy子类时只需实现create方法,无需修改父类代码。

方案二:构造函数类型断言

直接通过this.constructor获取当前实例的构造函数,结合类型断言创建新实例:

abstract class Enemy {
    abstract readonly attackPower: number;

    constructor(
        public readonly health: number
    ) {
    }

    hit(): this {
        // 断言构造函数接收number参数并返回当前类型实例
        const Constructor = this.constructor as new (health: number) => this;
        return new Constructor(this.health - 1);
    }
}

class Boss extends Enemy {
    attackPower = 100;
}

class NormalEnemy extends Enemy {
    attackPower = 5;
}

该方案代码简洁,但要求所有子类构造函数仅接收health一个参数,否则会出现运行时错误。

方案三:泛型约束抽象类

通过泛型参数绑定子类类型,明确构造函数的返回类型:

abstract class Enemy<T extends Enemy<T>> {
    abstract readonly attackPower: number;

    constructor(
        public readonly health: number
    ) {
    }

    hit(): T {
        const Constructor = this.constructor as new (health: number) => T;
        return new Constructor(this.health - 1);
    }
}

class Boss extends Enemy<Boss> {
    attackPower = 100;
}

class NormalEnemy extends Enemy<NormalEnemy> {
    attackPower = 5;
}

该方案类型约束更严谨,子类需显式指定泛型参数,确保返回类型准确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 09:27:28