Nest.js + sequelize generic service repository layer

Viewed 27

I am trying to build a generic service-repository layer for my nest.js starter kit with sequelize orm and PostgreSQL. I am almost done but I have a problem with the VS code/ Sequelize error. Here is my Generic service repository file

import { BadGatewayException } from '@nestjs/common';
import { Repository } from 'sequelize-typescript';
import { Attributes, WhereOptions } from 'sequelize/types';
import { BaseEntity } from './base.entity';
import { IBaseService } from './IBaseService';

export class BaseService<T extends BaseEntity<T>> implements IBaseService<T> {
  constructor(private readonly genericRepository: Repository<T>) {}
  async getAll(): Promise<T[]> {
    try {
      return await this.genericRepository.findAll();
    } catch (error) {
      throw new BadGatewayException(error);
    }
  }
  async get(id: string): Promise<T> {
    try {
      return await this.genericRepository.findByPk(id);
    } catch (error) {
      throw new BadGatewayException(error);
    }
  }
  async create(entity: any): Promise<T> {
    try {
      return await this.genericRepository.create(entity);
    } catch (error) {
      throw new BadGatewayException(error);
    }
  }
  async put(entity: Partial<T>, id: string): Promise<boolean> {
    try {
      return (
        (await this.genericRepository.update(entity, {
          where: { id: id },
        })[0]) > 0
      );
    } catch (error) {
      throw new BadGatewayException(error);
    }
  }

  async delete(id: string) {
    try {
      const whereOptions: WhereOptions = { id: id };
      return (await this.genericRepository.destroy(whereOptions)[0]) > 0;
    } catch (error) {
      throw new BadGatewayException(error);
    }
  }
}

Now if you hover over "where" word in put method, VS Code will show you this error message.

(property) where: WhereOptions<Attributes<T>>
Options to describe the scope of the search.

No overload matches this call.
  Overload 1 of 2, '(this: ModelStatic<...>, values: { [key in keyof Attributes<T>]?: Fn | Col | Literal | Attributes<T>[key]; }, options: Omit<UpdateOptions<Attributes<T>>, "returning"> & { ...; }): Promise<...>', gave the following error.
    Type '{ id: string; }' is not assignable to type 'WhereOptions<Attributes<T>>'.
      Types of property 'id' are incompatible.
        Type 'string' is not assignable to type 'WhereAttributeHashValue<Attributes<T>["id"]>'.
  Overload 2 of 2, '(this: ModelStatic<...>, values: { [key in keyof Attributes<T>]?: Fn | Col | Literal | Attributes<T>[key]; }, options: UpdateOptions<Attributes<T>>): Promise<...>', gave the following error.
    Type '{ id: string; }' is not assignable to type 'WhereOptions<Attributes<T>>'.
      Types of property 'id' are incompatible.
        Type 'string' is not assignable to type 'WhereAttributeHashValue<Attributes<T>["id"]>'.ts(2769)
model.d.ts(1144, 3): The expected type comes from property 'where' which is declared here on type 'Omit<UpdateOptions<Attributes<T>>, "returning"> & { returning: true | (keyof Attributes<T>)[]; }'
model.d.ts(1144, 3): The expected type comes from property 'where' which is declared here on type 'UpdateOptions<Attributes<T>>'

Here are my other files for import base.entity.ts

import { Exclude } from 'class-transformer';
import { Column, Model } from 'sequelize-typescript';
import { uuidv4 } from 'uuid';

export class BaseEntity<T> extends Model<T> {
  @Column({
    primaryKey: true,
    type: 'uuid',
    defaultValue: () => uuidv4(),
  })
  id: string;

  @Exclude()
  createdAt: Date;

  @Exclude()
  updatedAt: Date;

  @Exclude()
  deletedAt: Date;
}

IBaseService.ts

export interface IBaseService<T> {
  getAll(): Promise<T[]>;
  get(id: string): Promise<T>;
  create(entity: any): Promise<T>;
  put(entity: any, id: string): Promise<boolean>;
  delete(id: string): Promise<boolean>;
}

I hope we solve this problem, and thanks for your help in advance.

0 Answers
Related