I create a user model:
class UserModel extends Model {
static table = 'users'
static timestamps = true
static fields = {
id: { primaryKey: true, autoIncrement: true},
firstName: DataTypes.STRING,
lastName: DataTypes.STRING,
username: DataTypes.STRING,
email: DataTypes.STRING,
password: DataTypes.STRING,
birthday: DataTypes.DATE,
phoneNumber: DataTypes.INTEGER,
}
}
while I compare the existent user password with the new one:
async signin(user: Pick<User, "username" | "password">){
const { username, password } = user;
const existentUser = await UserModel.where('username', username).first()
if (!existentUser) throw new CustomErrorHandler(Status.NotFound, "User does not exist")
const isPasswordCorrect = await bcrypt.compare(password, existentUser.password); // Argument of type 'Function | FieldValue' // is not assignable to parameter of type 'string'.
// Type 'null' is not assignable to type 'string'.
}
I got this ts error:
Argument of type 'Function | FieldValue' is not assignable to parameter of type 'string'.
Type 'null' is not assignable to type 'string'.
I can fix it by forcing the type using :
const isPasswordCorrect = await bcrypt.compare(password, <string>existentUser.password);
but I'm looking for another solution. Is there another approach to convert returned Model by first() to User interface or something else?
In order to use typed fields on your models, you'll want to set up Model Records by duplicating the fields, like so:
Also, it looks like
/x/denodbdoesn't set up generic return types on the model functions. I was able to get your example to typecheck by only casting the return offirst()toUserModel. Here's the version ofsignin()that I was running myself:Needing to cast to the correct model seems like something that can be improved in
/x/denodb. I'll see if the project accepts a PR, but for now the above seems clean enough :)