dyedwiper
dyedwiper

Reputation: 338

MikroORM: How to use generic findOne with BaseEntity?

We are using MikroORM and would like to create a BaseRepo with some basic methods in our NestJS project. Doing so we ran into a problem with the findOne method. Here is our code:

BaseRepo.ts

export class BaseRepo<T extends BaseEntity> {
    constructor(protected readonly em: EntityManager) {}

    async findOneById(id: string): Promise<T> {
        const entity = await this.em.findOne(T, id); // ts complains here
        return entity;
    }
}

BaseEntity.ts

export abstract class BaseEntity {
    @PrimaryKey()
    _id!: ObjectId;

    @SerializedPrimaryKey()
    id!: string;
}

TypeScript gives us the following error on the T parameter of findeOne: 'T' only refers to a type, but is being used as a value here.ts(2693).

So it seems TypeScript does not recognize T as an Entity. Is there a way to make it work?

Upvotes: 1

Views: 1424

Answers (1)

Martin Ad&#225;mek
Martin Ad&#225;mek

Reputation: 18389

You need to use a value, not a type. Types dont exist during runtime, and you need a runtime value. Base repository should hold the entity name and you should be using that.

export class BaseRepo<T extends BaseEntity> {
    constructor(protected readonly em: EntityManager, protected entityName: EntityName<T>) {}

    async findOneById(id: string): Promise<T> {
        const entity = await this.em.findOne(this.entityName, id);
        return entity;
    }
}

Upvotes: 2

Related Questions