Clu*_*dch 25 mongoose node.js typescript
我目前正在尝试向我的mongoose架构添加一个静态方法,但我找不到它不能以这种方式工作的原因.
我的模特:
import * as bcrypt from 'bcryptjs';
import { Document, Schema, Model, model } from 'mongoose';
import { IUser } from '../interfaces/IUser';
export interface IUserModel extends IUser, Document {
comparePassword(password: string): boolean;
}
export const userSchema: Schema = new Schema({
email: { type: String, index: { unique: true }, required: true },
name: { type: String, index: { unique: true }, required: true },
password: { type: String, required: true }
});
userSchema.method('comparePassword', function (password: string): boolean {
if (bcrypt.compareSync(password, this.password)) return true;
return false;
});
userSchema.static('hashPassword', (password: string): string => {
return bcrypt.hashSync(password);
});
export const User: Model<IUserModel> = model<IUserModel>('User', userSchema);
export default User;
Run Code Online (Sandbox Code Playgroud)
IUSER:
export interface IUser {
email: string;
name: string;
password: string;
}
Run Code Online (Sandbox Code Playgroud)
如果我现在尝试打电话,User.hashPassword(password)我收到以下错误[ts] Property 'hashPassword' does not exist on type 'Model<IUserModel>'.
我知道我没有在任何地方定义方法,但我真的不知道我可以把它放在哪里,因为我不能只是将静态方法放入接口.我希望你能提前帮助我找到错误!
Har*_*ton 58
我遇到了和你一样的问题,然后在阅读了TS mongoose打字机的文档之后终于设法解决了它(之前我不知道,我不知道文档有多长时间了),特别是这一节.我知道这是一个非常古老的问题,但我认为它可能有助于将来失去一些人. 编辑:我在2014年3月读到现有答案的日期,而不是3月14日.
至于你的情况,你会希望遵循与你现有的类似的模式,虽然你需要在两个文件中改变一些东西.
IUser文件
IUser为IUserDocument.这是为了将您的架构与实例方法分开.Document从猫鼬进口.Document.模型文件
IUserto的所有实例IUserDocument,包括模块路径.IUserModelto 的定义IUser.IUser从,延伸IUserDocument, Document到的IUserDocument.IUserModelextends 的新接口Model<IUser>.IUserModel.User常量类型更改Model<IUserModel>为IUserModel,如IUserModel现在扩展Model<IUser>.<IUserModel>为<IUser, IUserModel>.以下是您的模型文件与这些更改的外观:
import * as bcrypt from 'bcryptjs';
import { Document, Schema, Model, model } from 'mongoose';
import { IUserDocument } from '../interfaces/IUserDocument';
export interface IUser extends IUserDocument {
comparePassword(password: string): boolean;
}
export interface IUserModel extends Model<IUser> {
hashPassword(password: string): string;
}
export const userSchema: Schema = new Schema({
email: { type: String, index: { unique: true }, required: true },
name: { type: String, index: { unique: true }, required: true },
password: { type: String, required: true }
});
userSchema.method('comparePassword', function (password: string): boolean {
if (bcrypt.compareSync(password, this.password)) return true;
return false;
});
userSchema.static('hashPassword', (password: string): string => {
return bcrypt.hashSync(password);
});
export const User: IUserModel = model<IUser, IUserModel>('User', userSchema);
export default User;
Run Code Online (Sandbox Code Playgroud)
你的(新重命名的)../interfaces/IUserDocument模块看起来像这样:
import { Document } from 'mongoose';
export interface IUserDocument extends Document {
email: string;
name: string;
password: string;
}
Run Code Online (Sandbox Code Playgroud)
Nat*_*May 12
我认为你遇到的问题与我刚刚遇到的问题相同.此问题在您的电话中.有几个教程可以.comparePassword()像这样从模型中调用方法.
User.comparePassword(candidate, cb...)
Run Code Online (Sandbox Code Playgroud)
这不起作用,因为方法是在schema不上model.我能够调用该方法的唯一方法是使用标准的mongoose/mongo查询方法找到该模型的实例.
这是我的护照中间件的相关部分:
passport.use(
new LocalStrategy({
usernameField: 'email'
},
function (email: string, password: string, done: any) {
User.findOne({ email: email }, function (err: Error, user: IUserModel) {
if (err) throw err;
if (!user) return done(null, false, { msg: 'unknown User' });
user.schema.methods.comparePassword(password, user.password, function (error: Error, isMatch: boolean) {
if (error) throw error;
if (!isMatch) return done(null, false, { msg: 'Invalid password' });
else {
console.log('it was a match'); // lost my $HÏT when I saw it
return done(null, user);
}
})
})
})
);
Run Code Online (Sandbox Code Playgroud)
所以我findOne({})以前得到了文档实例,然后通过挖掘文档中的模式属性来访问模式方法 user.schema.methods.comparePassword
我发现了一些不同之处:
instance方法而你的static方法是一种方法.我有信心有类似的方法访问策略.comparePassword()函数.也许这对静力学没有必要,但我无法访问this.password对于未来的读者:
请记住,我们正在处理两种不同的Mongo / Mongoose概念:模型和文档。
可以从一个模型中创建许多文档。模型是蓝图,文档是根据模型的说明创建的事物。
每个文档包含其自己的数据。每个实例还带有自己的实例方法,这些实例方法与自己的方法绑定在一起,this并且只能在该特定实例上运行。
模型可以具有“静态”方法,这些方法不与特定的Document实例绑定,而是在整个Document集合上运行。
这与TypeScript有何关系:
.method函数的类型。.static函数的类型。这里的其他答案都有不错的代码,因此请仔细阅读并找出文档定义方式和模型定义之间的差异。
记住,当您在代码中使用这些东西时,该模型用于创建新的Documents并调用诸如User.findOne或您的自定义静态变量(User.hashPassword如上定义)之类的静态方法。
文档是您用来从对象访问特定数据或调用实例方法(如上面定义的)this.save和自定义实例方法(如this.comparePassword上面定义的)的工具。
| 归档时间: |
|
| 查看次数: |
14265 次 |
| 最近记录: |