[TypeScript] Typing the Promise returned by a query
Closed this issue · 1 comments
Using TypeScript in my application, I have a UserModel
defined like this:
import { Instance } from 'sequelize';
interface IUserAttributes {
id: number;
first_name: string;
last_name: string;
...
}
type UserModel = Instance<IUserAttributes> & IUserAttributes;
All good till there. I want to type the function I to query users:
const findUsers = () => db.User.findAll();
const findUserById = (id: number) => db.User.findById(id);
My first try was:
const findUsers = (): Promise<UserModel[]> => db.User.findAll();
const findUserById = (id: number): Promise<UserModel | null> => db.User.findById(id);
I got the following errors:
error TS2322: Type 'Bluebird<{}[]>' is not assignable to type 'Promise<UserModel[]>'.
error TS2322: Type 'Bluebird<{} | null>' is not assignable to type 'Promise<UserModel | null>'.
Okay, so I tried:
import * as Bluebird from 'bluebird';
const findUsers = (): Bluebird<UserModel[]> => db.User.findAll();
const findUserById = (id: number): Bluebird<UserModel | null> => db.User.findById(id);
I got this errors:
error TS2322: Type 'Bluebird<{}[]>' is not assignable to type 'Bluebird<UserModel[]>'.
error TS2322: Type 'Bluebird<{} | null>' is not assignable to type 'Bluebird<UserModel | null>'.
Keep trying:
import * as Bluebird from 'bluebird';
const findUsers = (): Bluebird<UserModel[]> => db.User.findAll() as Bluebird<UserModel[]>;
const findUserById = (id: number): Bluebird<UserModel | null> => db.User.findById(id) as Bluebird<UserModel | null>;
One of them is working, but the promise returning the array of Model still fail:
error TS2352: Type 'Bluebird<{}[]>' cannot be converted to type 'Bluebird<UserModel[]>'.
At this point I'm not really sure anymore what to do. In my last resort I used PromiseLike
instead of Bluebird
:
const findUsers = (): PromiseLike<UserModel[]> => db.User.findAll();
const findUserById = (id: number): PromiseLike<UserModel | null> => db.User.findById(id);
However now I cannot use .catch()
now:
error TS2339: Property 'catch' does not exist on type 'PromiseLike'.
Please help, I was surprise to not find anything about this :/
It's usually when you post something that you find the solution. Turns out that you just need to type the model correctly. I had the following:
import Sequelize from 'sequelize';
interface IModelsObject {
User: Sequelize.Model<{},{}>;
}
const models: IModelsObject = {
User: sequelize.import(`${modelPath}/User`),
};
I just updated it like this:
interface IModelsObject {
User: Sequelize.Model<UserModel, IUserAttributes>;
}
const models: IModelsObject = {
User: sequelize.import(`${modelPath}/User`),
};
I hope this help someone some day...