使用 TypeScript 创建猫鼬模式方法

Dan*_*sky 7 mongoose node.js typescript

我尝试为用户模式创建 hashPassword 方法。

schema.method("hashPassword", function (): void {
  const salt = bcrypt.genSaltSync(10);
  const hash = bcrypt.hashSync(this.password, salt);

  this.password = hash;
});
Run Code Online (Sandbox Code Playgroud)

Property 'password' does not exist on type 'Document<any>'.并收到密码错误

这是我的文件

import mongoose, { Schema, Document } from "mongoose";
import bcrypt from "bcryptjs";

/**
 * This interface should be the same as JWTPayload declared in types/global.d.ts file
 */
export interface IUser extends Document {
  name: string;
  email: string;
  username: string;
  password: string;
  confirmed: boolean;
  hashPassword: () => void;
  checkPassword: (password: string) => boolean;
}

// User schema
const schema = new Schema(
  {
    name: {
      type: String,
      required: true,
    },
    email: {
      type: String,
      required: true,
    },
    username: {
      type: String,
      required: true,
    },
    password: {
      type: String,
      required: true,
    },
    confirmed: {
      type: Boolean,
      default: false,
    },
  },
  { timestamps: true }
);

schema.method("hashPassword", function (): void {
  const salt = bcrypt.genSaltSync(10);
  const hash = bcrypt.hashSync(this.password, salt);

  this.password = hash;
});

// User model
export const User = mongoose.model<IUser>("User", schema, "users");

Run Code Online (Sandbox Code Playgroud)

Lin*_*ste 9

在定义方法时,schema对象不知道它是Schemafor anIUser而不仅仅是 any Document。您需要在Schema创建时设置泛型类型:new Schema<IUser>( ... )


Viv*_*ary 6

根据 mongoose 的一位合作者的建议,我们可以使用以下方式来创建实例方法:

const schema = new Schema<ITestModel, Model<ITestModel, {}, InstanceMethods>> // InstanceMethods would be the interface on which we would define the methods

schema.methods.methodName = function() {}

const Model = model<ITestModel, Model<ITestModel, {}, InstanceMethods>>("testModel", ModelSchema)

const modelInstance = new Model();
modelInstance.methodName() // works
Run Code Online (Sandbox Code Playgroud)

链接:https ://github.com/Automattic/mongoose/issues/10358#issuecomment-861779692


The*_*MCA 5

这使得足够清楚

import mongoose, { Schema, Document, Model } from "mongoose";
import bcrypt from "bcrypt";

interface IUser {
    username: string;
    hashedPassword: string;
}

interface IUserDocument extends IUser, Document {
    setPassword: (password: string) => Promise<void>;
    checkPassword: (password: string) => Promise<boolean>;
}

interface IUserModel extends Model<IUserDocument> {
    findByUsername: (username: string) => Promise<IUserDocument>;
}

const UserSchema: Schema<IUserDocument> = new Schema({
    username: { type: String, required: true },
    hashedPassword: { type: String, required: true },
});

UserSchema.methods.setPassword = async function (password: string) {
    const hash = await bcrypt.hash(password, 10);
    this.hashedPassword = hash;
};

UserSchema.methods.checkPassword = async function (password: string) {
    const result = await bcrypt.compare(password, this.hashedPassword);
    return result;
};

UserSchema.statics.findByUsername = function (username: string) {
    return this.findOne({ username });
};

const User = mongoose.model<IUserDocument, IUserModel>("User", UserSchema);
export default User;
Run Code Online (Sandbox Code Playgroud)

  • 确保在定义方法时不要使用箭头函数!我通常到处写箭头函数,但我忘记了箭头函数中没有“this”。我花了几分钟才想起这一点。 (3认同)