Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sequelize-Typescript typeof model

I'm trying to create a base crud service that takes a Sequelize model and creates all basic APIs for it so what I have done it this:

export class RepositoryService<T extends Model<T>> {
  constructor(protected model: typeof Model) {
  }
  public async getMany(
    query: RequestParamsParsed = {},
    options: RestfulOptions = {},
  ): Promise<T[]> {
    return this.model.findAll();
  }
}

I'm getting the following error:

The 'this' context of type 'typeof Model' is not assignable to method's 'this' of type 'new () => Model<Model<any>>'.
  Cannot assign an abstract constructor type to a non-abstract constructor type.

this is because of this line in the seqeulize-typescript package:

static findAll<T extends Model<T>>(this: (new () => T), options?: IFindOptions<T>): Promise<T[]>;

I'm relatively new to Typescript so if anyone can tell me what's the meaning of this: (new () => T) in the findAll function and how can I work this out.

like image 959
Sami Avatar asked Mar 14 '19 15:03

Sami


2 Answers

Also encountered this error while working with the sequelize-typescript library.

You could first define these helper types:

import { Model } from "sequelize-typescript";

// Type `ModelType` would basically wrap & satisfy the 'this' context of any sequelize helper methods
type Constructor<T> = new (...args: any[]) => T;
type ModelType<T extends Model<T>> = Constructor<T> & typeof Model;

Then, use it with your code:

export class RepositoryService<T extends Model<T>> {
  constructor(protected model: ModelType<T>) {}

  public async getMany(
    query: RequestParamsParsed = {},
    options: RestfulOptions = {},
  ): Promise<T[]> {
    return this.model.findAll();
  }
}

Hope this helps.

like image 146
Adrian Avatar answered Sep 26 '22 16:09

Adrian


The problem seemed to be in this line

constructor(protected model: typeof Model) {}

The Model I was setting the model type to is imported from sequelize-typescript while I should use the original model exported from sequelize itself.

The whole code is like this:

import { Model as OriginalModel } from 'sequelize';
import { Model } from 'sequelize-typescript';
export class RepositoryService<T extends Model<T>> {
  constructor(protected model: typeof OriginalModel) {
  }
  public async getMany(
    query: RequestParamsParsed = {},
    options: RestfulOptions = {},
  ): Promise<T[]> {
    return this.model.findAll();
  }
}
like image 28
Sami Avatar answered Sep 25 '22 16:09

Sami