'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 |