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

如何在NestJS TypeScript中实现一个类继承多个类?

TypeScript实现类多继承需求的解决方案

问题描述

现有如下TypeScript代码,想要创建User类同时继承UserRegisterParams和Common类,拿到两者所有属性和方法:

export class UserInitialParams {
  @ApiProperty({example: 'john@doe.com', description: 'Email'})
  @Prop({required: true})
  email: string;

  @ApiProperty({example: 'admin', description: 'Role'})
  @Prop({required: true, default: 'admin'})
  role: string;
}

export class UserRegisterParams extends UserInitialParams{
  @ApiProperty({example: 'asd123456', description: 'Password'})
  @Prop({required: true})
  password: string;
}

@Schema({timestamps: true})
export class Common {
    @Prop({ required: false, default: null })
    deletedAt: Date | null;

    @Prop({ required: false, default: false })
    isDeleted: boolean | null;

    softDelete: Function;
    unDelete: Function;
    isOwner: Function;

    constructor() {
        this.deletedAt = null;
        this.isDeleted = false;
    }
}

想写的代码(但TypeScript不支持这种多继承语法):

export class User extends UserRegisterParams, Common {}

解决方案

TypeScript本身不支持类的多继承,但可以用下面两种方式实现需求:

方法1:把Common改成接口+实现类

TypeScript允许类继承一个父类的同时实现多个接口。可以先把Common的属性和方法定义成接口,再用一个类实现这个接口,最后在User里继承UserRegisterParams并实现接口,同时复用Common的方法逻辑:

// 定义Common接口,规范属性和方法
export interface ICommon {
    deletedAt: Date | null;
    isDeleted: boolean | null;
    softDelete(): void;
    unDelete(): void;
    isOwner(): boolean;
}

// 保留Common类作为接口的实现,复用方法逻辑
@Schema({timestamps: true})
export class Common implements ICommon {
    @Prop({ required: false, default: null })
    deletedAt: Date | null;

    @Prop({ required: false, default: false })
    isDeleted: boolean | null;

    constructor() {
        this.deletedAt = null;
        this.isDeleted = false;
    }

    softDelete(): void {
        this.deletedAt = new Date();
        this.isDeleted = true;
    }

    unDelete(): void {
        this.deletedAt = null;
        this.isDeleted = false;
    }

    isOwner(): boolean {
        // 这里写你的业务逻辑
        return true;
    }
}

// 创建User类:继承UserRegisterParams,实现ICommon接口
export class User extends UserRegisterParams implements ICommon {
    @Prop({ required: false, default: null })
    deletedAt: Date | null;

    @Prop({ required: false, default: false })
    isDeleted: boolean | null;

    softDelete: () => void;
    unDelete: () => void;
    isOwner: () => boolean;

    constructor() {
        super();
        // 把Common的实例方法和属性复制到当前实例
        Object.assign(this, new Common());
    }
}

方法2:使用Mixin混入模式

Mixin是TypeScript里用来复用多个类功能的常用模式,适合需要整合多个类逻辑的场景:

// 先定义一个构造函数类型,方便后续处理
type Constructor<T = {}> = new (...args: any[]) => T;

// 写一个工具函数,用来把混入类的属性和方法挂载到目标类原型上
function applyMixin<T extends Constructor<any>>(baseClass: T, mixins: Constructor<any>[]) {
    mixins.forEach(mixin => {
        // 复制原型上的方法
        Object.getOwnPropertyNames(mixin.prototype).forEach(propName => {
            if (propName !== 'constructor') {
                baseClass.prototype[propName] = mixin.prototype[propName];
            }
        });
        // 复制实例属性
        const mixinInstance = new mixin();
        Object.getOwnPropertyNames(mixinInstance).forEach(propName => {
            baseClass.prototype[propName] = mixinInstance[propName];
        });
    });
}

// 创建User类,先继承UserRegisterParams
export class User extends UserRegisterParams {
    @Prop({ required: false, default: null })
    deletedAt: Date | null;

    @Prop({ required: false, default: false })
    isDeleted: boolean | null;

    softDelete: Function;
    unDelete: Function;
    isOwner: Function;

    constructor() {
        super();
        this.deletedAt = null;
        this.isDeleted = false;
    }
}

// 把Common类的功能混入到User里
applyMixin(User, [Common]);

注意点

  • 因为你用了@Prop(Mongoose)和@ApiProperty(Swagger)这些装饰器,所以User里的属性必须手动加上对应的装饰器,不然Mongoose不会把这些字段映射到数据库,Swagger也生成不了正确的API文档。
  • 如果两个父类有同名的属性或方法,得手动处理冲突,避免被意外覆盖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 12:15:10