Search code examples
typescripttypeorm

Class generic parameter constraint is not passed down to class properties


I am trying to use TypeScript with TypeORM with a generic class. Notice my AbstractDal takes a generic parameter where I constraint it such that it has to extend IEntity and IEntity has a id property. But for some reason, id property is not passed down to repository and it doesn't see that my findOneBy function call should type check. I am not sure if it's a TypeScript limitation or a TypeORM limitation.

interface IEntity {
  id: number;
}

export abstract class AbstractDal<T extends IEntity> {
  abstract repository: Repository<T>;

  public async get(id: number): Promise<T> {
    return await this.repository.findOneBy({ id });
  }
}

Error:

src/abstracts/abstract.dal.ts:20:44 - error TS2345: Argument of type '{ id: number; }' is not assignable to parameter of type 'FindOptionsWhere<T> | FindOptionsWhere<T>[]'.
  Types of property 'id' are incompatible.
    Type 'number' is not assignable to type 'FindOptionsWhereProperty<NonNullable<T["id"]>, NonNullable<T["id"]>>'.

20     return await this.repository.findOneBy({ id });

Repository. Just call npm i && npm start to see the problem.


Solution

  • you can explicitly define the type of where statement on findOne() function.

     public async get(id: number): Promise<T> {
        const findOptions: FindOneOptions<T> = {
          where: {
            id: id,
          } as FindOptionsWhere<T>,
        };
        return await this.repository.findOne(findOptions);
      }
    

    indeed i put AbstractDal class like that

    export abstract class AbstractDal<T extends Record<string, any> & IEntity>