[英]Create mongoose schema methods using TypeScript
我尝试为用户模式创建方法 hashPassword。
schema.method("hashPassword", function (): void {
const salt = bcrypt.genSaltSync(10);
const hash = bcrypt.hashSync(this.password, salt);
this.password = hash;
});
并得到一个错误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");
在定义方法时, schema
object 不知道它是IUser
的Schema
而不仅仅是任何Document
。 创建Schema
时需要为它设置泛型类型: new Schema<IUser>(... )
。
您应该声明一个扩展 Model 的接口,如下所示:
interface IUser {...}
interface IUserInstanceCreation extends Model<IUser> {}
然后声明你的模式;
const userSchema = new Schema<IUser, IUserInstanceCreation, IUser>({...})
这也将确保 Schema 遵循 IUser 中的属性。
正如 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
链接: https://github.com/Automattic/mongoose/issues/10358#issuecomment-861779692
这很清楚
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;
避免必须重新定义模式中已经存在的类型的解决方案
import { Schema, model, InferSchemaType } from "mongoose"
import bcrypt from "bcrypt"
const userSchema = new Schema({
name: String,
email: {
type: String,
required: true,
unique: true
},
password: String,
})
userSchema.methods.verifyPassword = async function(password: string){
return await bcrypt.compare(password, this.password)
}
declare interface IUser extends InferSchemaType<typeof userSchema> {
verifyPassword(password: string): boolean
}
export const UserModel = model<IUser>("Users", userSchema)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.