2
votes

For whatever reason typescript is not accepting my code. In the UserScema.pre method the typescript error says the properties createdAt, and password do not exist on the type Document (this). How can I make the typescript interface apply to this method and return an IUserDocument object?

import {Schema, Model, Document, model} from 'mongoose';
import bcrypt from 'bcrypt-nodejs';

export interface IUserDocument extends Document{
    createdAt: Date,
    username: string,
    displayName: string,
    email: string,
    googleId: string,
    password: string,
    verifyPassword(password:string): boolean
}

let UserSchema: Schema = new Schema({
    createdAt:{
        type:Date,
        default:Date.now   
    },
    username: {
        type:String,
        lowercase:true  
    },
    displayName: String,
    email: {
        type:String,
        lowercase:true
    },
    googleId: String,
    password: String
});

UserSchema.pre('save', function(next){
    var user = this;

    if(!this.createdAt) this.createdAt = Date.now;

    if(user.isModified('password')) {
        bcrypt.genSalt(10, function(err:any, salt:number){
            bcrypt.hash(user.password, salt, null, function(err:any, hash:string){
                if(err) return next(err);
                user.password = hash; 
                next();
            });
        });
    } else{
        return next();
    }
});

UserSchema.methods.verifyPassword = function(password:string){
    return bcrypt.compareSync(password, this.password);
}

const User = model<IUserDocument>('User', UserSchema);
export default User;

My code is derived from this source http://brianflove.com/2016/10/04/typescript-declaring-mongoose-schema-model/.

1

1 Answers

5
votes

pre is generic method which parameter defaults to Document. In case this is not so, it should be:

UserSchema.pre<IUserDocument>('save', function(next){ ... });