denodb icon indicating copy to clipboard operation
denodb copied to clipboard

Argument of type 'Function | FieldValue' is not assignable to parameter of type 'string'.

Open slim-hmidi opened this issue 3 years ago • 1 comments

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?

slim-hmidi avatar Dec 18 '21 16:12 slim-hmidi

You can use a cast on the returned value, and there is a way to set the model fields when defining the class.

Example:

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,
    }
    id!: number;
    firstName!: string;
    lastName!: string;
    username!: string;
    email!: string;
    password!: string;
    birthday!: Date;
    phoneNumber!: number;
}

And then in your query:

async signin(user: Pick<User, "username" | "password">){
        const { username, password } = user;

    const existentUser = await UserModel.where('username', username).first() as UserModel; // cast to your model class.

    if (!existentUser) throw new CustomErrorHandler(Status.NotFound, "User does not exist")

    const isPasswordCorrect = await bcrypt.compare(password, existentUser.password);
}

envis10n avatar Mar 07 '22 21:03 envis10n