'NestJS - How do I create a generic service?

I'm trying to create a generic service but not a generic database repository.

I already have a generic repository for database logic. This works.

// entity.repository.ts
export abstract class EntityRepository<T extends Document> {
  constructor(protected readonly entityModel: Model<T>) {}

  async find(): { }
}

Elsewhere I have a UsersRepository that extends the EntityRepository. This works.

// users.repository.ts
@Injectable()
export class UsersRepository extends EntityRepository<UserDocument> {
    constructor(@InjectModel(User.name) userModel: Model<UserDocument>) {
        super(userModel)
    }
}

I want to create a generic service that can take in different instances of the entity repository, so it can be a UsersRepository, CatRepository or DogRepository so it's defined generically here. I'm having trouble defining the type for this generic repository. The actual injected repository here will be an instance of entityRepository - for example, the UsersRepository above should be able to be injected in this EntityService.

// entity.service.ts
@Injectable()
export abstract class EntityService<T extends Document> {
  constructor(
    protected readonly entityRepostiory: EntityRepository<T>,
    private readonly myOtherService1: MyOtherService1,
    private readonly MyOtherService2: MyOtherService2,
  )

  public myMethod() {
    // Property 'find' does not exist on type 'EntityRepository<T>'
    const user = this.entityRepository.find({}); // <- Type error
  }
}

And then I want to create an instance of the above base EntityService. Not sure how to type this out properly either

// cat.service.ts
@Injectable()
export class CatService extends EntityService<CatDocument> { // <- not sure about typing
  constructor(
    private readonly catRepository: CatRepository<CatDocument>, // <- ???
    private readonly myOtherService1: MyOtherService1,
    private readonly MyOtherService2: MyOtherService2,
    ) {
    super(catRepository, myOtherService1, myOtherService2) // <- I need to call super on all 3 right?
  } 
}


Sources

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

Source: Stack Overflow

Solution Source