'Nestjs create Generic CRUD service

I want to create a base service using a generic class which I wrote below:


import { BaseEntity } from './base.entity';
import { Repository } from 'typeorm';

export class BaseService<Entity extends BaseEntity> {
  constructor(private entitiesRepository: Repository<Entity>) {}

  findById(id: number): Promise<Entity> {
    return this.entitiesRepository.findOneBy({ id });
  }
}

When I try it, I get the following error:

Argument of type '{ id: number; }' is not assignable to parameter of type 'FindOptionsWhere<Entity> | FindOptionsWhere<Entity>[]'.
Types of property 'id' are incompatible.     
Type 'number' is not assignable to type 'FindOptionsWhereProperty<NonNullable<Entity["id"]>>'


This is my base entity class:

// base.entity.ts
import {
  Column,
  PrimaryGeneratedColumn,
  CreateDateColumn,
  UpdateDateColumn,
} from 'typeorm';

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

  @Column({ default: false })
  isDeleted: boolean;

  @CreateDateColumn()
  createdAt: Date;

  @UpdateDateColumn()
  updatedAt: Date;
}

How can I fix this problem?



Solution 1:[1]

None of the above answers fixed the issue. I found an open issue on TypeORM GitHub relating to this problem.

For now, I fixed this with any type. I know it is not perfect but, it is working for now. I'm looking forward to any other solutions.

import { BaseEntity } from './base.entity';
import { Repository } from 'typeorm';

export class BaseService<Entity extends BaseEntity> {
  constructor(private entitiesRepository: Repository<Entity>) {}

  findById(id: any): Promise<Entity> {
    return this.entitiesRepository.findOneBy({ id });
  }
}

Solution 2:[2]

I think you are using an outdated version of typeorm. findOneBy is deprecated and removed in the recent releases.

Update typeorm and try this:

findById(id: number): Promise<Entity> {
    return this.entitiesRepository.findOne(id);
}

Solution 3:[3]

You need to decorate your BaseEntity class @Entity() as stated in the documentation : https://docs.nestjs.com/techniques/database#repository-pattern

// base.entity.ts
import {
  Entity,
  Column,
  PrimaryGeneratedColumn,
  CreateDateColumn,
  UpdateDateColumn,
} from 'typeorm';

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

  @Column({ default: false })
  isDeleted: boolean;

  @CreateDateColumn()
  createdAt: Date;

  @UpdateDateColumn()
  updatedAt: Date;
}

Solution 4:[4]

I'm no expert here, but I think typescript is complaining that BaseEntity doesn't extend ObjectLiteral:

https://github.com/typeorm/typeorm/blob/master/src/repository/Repository.ts#L22 https://github.com/typeorm/typeorm/blob/master/src/common/ObjectLiteral.ts

I think all you need to do is add "extends ObjectLiteral" and the corresponding import to BaseEntity.

Like:

import { ObjectLiteral } from 'typeorm';

And then:

export class BaseEntity extends ObjectLiteral {

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Parsa Ghadimkhani
Solution 2 Hamidreza Vakilian
Solution 3 Ugo Evola
Solution 4 Drew Delano