11

I am getting this error Property "password" does not exists on type Document. So can anyone tell if there is something wrong with my code ?

const userSchema = new mongoose.Schema({
  email: { type: String, required: true, unique: true },
  password: { type: String, required: true },
  name: { type: String, required: true }
});

userSchema.pre("save", function save(next) {
  const user = this;
  if (!user.isModified("password")) {
    return next();
  }
  bcrypt.genSalt(10, (err, salt) => {
    if (err) {
      return next(err);
    }
    bcrypt.hash(user.password, salt, (err: mongoose.Error, hash) => {
      if (err) {
        return next(err);
      }
      user.password = hash;
      next();
    });
  });
});

enter image description here

Barometer
  • 368
  • 3
  • 8
  • 1
    See [Using mongoose pre-save hook with typescript](https://github.com/Automattic/mongoose/issues/5046#issuecomment-412114160) – Shivam Jha Jan 23 '21 at 11:24

4 Answers4

20

You need to add type here with pre-save hook as per the mongoose docs, pre hook is defined as,

/**
 * Defines a pre hook for the document.
 */
pre<T extends Document = Document>(
  method: "init" | "validate" | "save" | "remove",
  fn: HookSyncCallback<T>,
  errorCb?: HookErrorCallback
): this;

and if you have an interface like below then,

export interface IUser {
  email: string;
  password: string;
  name: string;
}

Add type with pre-save hook,

userSchema.pre<IUser>("save", function save(next) { ... }
Shivam Pandey
  • 3,756
  • 2
  • 19
  • 26
7

I dont know if this will help as the question is old now, however I tried this

import mongoose, { Document } from 'mongoose';

const User = mongoose.model<IUser & Document>("users", UserSchema);

type IUser = {
    username: string
    password: string
}

mongoose.model needs a Document type, and you want to extend that document, therefore Unify the two types

5

you can also pass the interface type to the schema itself.

import { model, Schema, Document } from 'mongoose';

const userSchema = new mongoose.Schema<IUser>({
  email: { type: String, required: true, unique: true },
  password: { type: String, required: true },
  name: { type: String, required: true }
});

interface IUser extends Document{
  email: string;
  password: string;
  name: string;
}
samehanwar
  • 3,280
  • 2
  • 23
  • 26
-1

Declare the .pre function shortly after schema construction, after the interface with the fields defined, is declared.

Image for reference

sr9yar
  • 4,850
  • 5
  • 53
  • 59