mongoose 属性 'password' 在类型 'Document<any> 上不存在
mongoose property 'password' does not exist on type 'Document<any>
-- userSchema.ts 界面
import mongoose, { Schema, Document } from "mongoose";
import moment from "moment";
import bcrypt from "bcrypt";
export interface UserDoc extends Document {
name: {
type: string;
required: boolean;
};
email: {
type: string;
required: boolean;
};
password: {
type: string;
required: boolean;
};
dateJoined: {
type: string;
default: string;
};
}
const userSchema = new Schema({
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
},
password: {
type: String,
required: true,
},
dateJoined: {
type: String,
default: moment().format("MMMM Do YYYY"),
},
});
我创建了我的用户模型,我遇到的问题是创建 matchPassword 方法并使用 bcrypt 比较 enteredPassword 参数与数据库中的密码
userSchema.methods.matchPassword = async function (enteredPassword) {
return await bcrypt.compare(enteredPassword, this.password); ***
};
userSchema.pre("save", async function (next) {
if (this.isModified("password")) {
next();
}
const salt = bcrypt.genSalt(10);
*** this.password = await bcrypt.hash(this.password, await salt); ***
});
const User = mongoose.model("User", userSchema);
报错信息如下:
Property 'password' does not exist on type 'Document<any>'.
并且此错误出现在由 ***
突出显示的 this.password 的每个实例上
我之前在 Javascript 中使用过同样的方法,所以我不知道为什么它在打字稿上不起作用,我该如何绑定 this.password到猫鼬文档
谢谢
不要在 return 中使用 await,所以只需尝试
userSchema.methods.matchPassword = async function (enteredPassword) {
let isValid = await bcrypt.compare(enteredPassword, this.password);
return isValid
};
并且你不需要在 bcrypt
中加入盐,之后第二个参数应该是一个数字
this.password = await bcrypt.hash(this.password, 12);
基于documentation如果你想使用盐你可以这样做
const bcrypt = require('bcrypt');
const saltRounds = 10;
const myPlaintextPassword = 's0/\/\P4$$w0rD';
const someOtherPlaintextPassword = 'not_bacon';
const salt = bcrypt.genSaltSync(saltRounds);
const hash = bcrypt.hashSync(myPlaintextPassword, salt);
看起来@Mohammad 已帮助您完成 bcrypt
实施。我可以帮助您解决打字稿错误!
UserDoc
是一个 typescript 接口,所以它不应该有像 required
这样的字段。它应该只描述 UserDoc
对象的类型。默认情况下需要属性。如果它们是可选的,我们使用 ?:
,但看起来这里都是必需的。
export interface UserDoc extends Document {
name: string;
email: string;
password: string;
dateJoined: string;
matchPassword: (pw: string) => Promise<boolean>
}
当你创建 userSchema
时,你通过设置 Schema
构造函数到 UserDoc
.
const userSchema = new Schema<UserDoc>({ ...
这清除了 userSchema.methods.matchPassword
中的错误,因为我们知道 this.password
是 string
。我们也知道 enteredPassword
是一个 string
因为我们在 UserDoc
接口中为这个 matchPassword
方法定义了参数。
出于某种原因,pre
方法无法自动识别我们的文档类型。但是 pre
方法本身是一个通用函数,所以我们可以再次指定我们的文档是 UserDoc
.
userSchema.pre<UserDoc>( ...
这很愚蠢,但我们必须在创建模型时再次指定通用。
const User = mongoose.model<UserDoc>("User", userSchema);
现在 User
的类型为 mongoose.Model<UserDoc, {}>
并且您调用的任何方法都应该 return 一个 UserDoc
而不仅仅是一个 Document
.
-- userSchema.ts 界面
import mongoose, { Schema, Document } from "mongoose";
import moment from "moment";
import bcrypt from "bcrypt";
export interface UserDoc extends Document {
name: {
type: string;
required: boolean;
};
email: {
type: string;
required: boolean;
};
password: {
type: string;
required: boolean;
};
dateJoined: {
type: string;
default: string;
};
}
const userSchema = new Schema({
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
},
password: {
type: String,
required: true,
},
dateJoined: {
type: String,
default: moment().format("MMMM Do YYYY"),
},
});
我创建了我的用户模型,我遇到的问题是创建 matchPassword 方法并使用 bcrypt 比较 enteredPassword 参数与数据库中的密码
userSchema.methods.matchPassword = async function (enteredPassword) {
return await bcrypt.compare(enteredPassword, this.password); ***
};
userSchema.pre("save", async function (next) {
if (this.isModified("password")) {
next();
}
const salt = bcrypt.genSalt(10);
*** this.password = await bcrypt.hash(this.password, await salt); ***
});
const User = mongoose.model("User", userSchema);
报错信息如下:
Property 'password' does not exist on type 'Document<any>'.
并且此错误出现在由 ***
突出显示的 this.password 的每个实例上我之前在 Javascript 中使用过同样的方法,所以我不知道为什么它在打字稿上不起作用,我该如何绑定 this.password到猫鼬文档
谢谢
不要在 return 中使用 await,所以只需尝试
userSchema.methods.matchPassword = async function (enteredPassword) {
let isValid = await bcrypt.compare(enteredPassword, this.password);
return isValid
};
并且你不需要在 bcrypt
中加入盐,之后第二个参数应该是一个数字
this.password = await bcrypt.hash(this.password, 12);
基于documentation如果你想使用盐你可以这样做
const bcrypt = require('bcrypt');
const saltRounds = 10;
const myPlaintextPassword = 's0/\/\P4$$w0rD';
const someOtherPlaintextPassword = 'not_bacon';
const salt = bcrypt.genSaltSync(saltRounds);
const hash = bcrypt.hashSync(myPlaintextPassword, salt);
看起来@Mohammad 已帮助您完成 bcrypt
实施。我可以帮助您解决打字稿错误!
UserDoc
是一个 typescript 接口,所以它不应该有像 required
这样的字段。它应该只描述 UserDoc
对象的类型。默认情况下需要属性。如果它们是可选的,我们使用 ?:
,但看起来这里都是必需的。
export interface UserDoc extends Document {
name: string;
email: string;
password: string;
dateJoined: string;
matchPassword: (pw: string) => Promise<boolean>
}
当你创建 userSchema
时,你通过设置 Schema
构造函数到 UserDoc
.
const userSchema = new Schema<UserDoc>({ ...
这清除了 userSchema.methods.matchPassword
中的错误,因为我们知道 this.password
是 string
。我们也知道 enteredPassword
是一个 string
因为我们在 UserDoc
接口中为这个 matchPassword
方法定义了参数。
出于某种原因,pre
方法无法自动识别我们的文档类型。但是 pre
方法本身是一个通用函数,所以我们可以再次指定我们的文档是 UserDoc
.
userSchema.pre<UserDoc>( ...
这很愚蠢,但我们必须在创建模型时再次指定通用。
const User = mongoose.model<UserDoc>("User", userSchema);
现在 User
的类型为 mongoose.Model<UserDoc, {}>
并且您调用的任何方法都应该 return 一个 UserDoc
而不仅仅是一个 Document
.