Can we extends multiple classes in NestJS for TypeORM?

Viewed 3753

I faced a situation where I want extends multiple classes. I have class A named a.entity.ts and I'm extending this class to BaseEntity (which is the predefined class in typeORM) as follow:

@Entity()
export class A extends BaseEntity{
    @PrimaryGeneratedColumn()
    id: number;

    @Column()
    title: string;

    @Column({length: 100, nullable: true})
    description: string;
}

Also, I have my own custom abstract class DateAudit for Auditing date purpose as follow:

export abstract class DateAudit {
    
    @CreateDateColumn()
    created: Date;
  
    @UpdateDateColumn()
    updated: Date;
  }

I want to use this DateAudit along with BaseEntity class in my class A like :

export class A extends BaseEntity, DateAudit

I know multiple inheritances are not possible. Looking forward to knowing how I can achieve this type of scenario.

Thanks in advance!

2 Answers

You can do it as follow:

export abstract class DateAudit extends BaseEntity {
    
    @CreateDateColumn()
    created: Date;
  
    @UpdateDateColumn()
    updated: Date;
  }

then your entity will do:

@Entity()
export class A extends DateAudit {
    @PrimaryGeneratedColumn()
    id: number;

    @Column()
    title: string;

    @Column({length: 100, nullable: true})
    description: string;
}

SOLUTION 1
To inherit columns in TypeORM you need to write an abstract class that your entity will inherit from, in your case you can do something:

    export type Constructor<T = {}> = new (...args: any[]) => T;

export function BaseEntity<TBase extends Constructor>(Base: TBase) {
    abstract class AbstractBase extends Base {
        @PrimaryGeneratedColumn()
          id: number;

        @Column()
         title: string;

       @Column({length: 100, nullable: true})
        description: string;
    }
    return AbstractBase;
}

export function DateAudit<TBase extends Constructor>(Base: TBase) {
    abstract class AbstractBase extends Base {
        @CreateDateColumn()
            created: Date;

        @UpdateDateColumn()
           updated: Date;
    }
    return AbstractBase;
}

export class EmptyClass {}

To implement it :

    @Entity()
export class A extends DateAudit(BaseEntity(EmptyClass)){
    @PrimaryGeneratedColumn()
    id: number;

    @Column()
    title: string;

    @Column({length: 100, nullable: true})
    description: string;
}

ps: inspired by solution from github


Solution 2 : is to use Embedded Entities

In your case, we going to extend the baseEntity, on the other hand we going to create a class for auditEntity

    export class DateAudit {
    
    @CreateDateColumn()
    created: Date;
  
    @UpdateDateColumn()
    updated: Date;
  }

Then we can connect those columns in your entity :

       @Entity()
export class A extends BaseEntity {
    @PrimaryGeneratedColumn()
    id: number;

    @Column()
    title: string;

    @Column({length: 100, nullable: true})
    description: string;

   @Column(type => DateAudit )
    audit: DateAudit ;
}

ps: the colmun will take audit as a prefix
source : embedded-entities

Related