一尘不染

Typescript猫鼬静态模型方法“类型上不存在属性”

node.js

我目前正在尝试向我的猫鼬模式中添加静态方法,但是我找不到它无法通过这种方式工作的原因。

我的模特:

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;

IUser:

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

如果我现在尝试拨打电话,User.hashPassword(password)则会出现以下错误[ts] Property 'hashPassword' does not exist on type 'Model<IUserModel>'.

我知道我没有在任何地方定义方法,但我真的不知道在哪里可以放置它,因为我不能只是将静态方法放到接口中。希望您能帮助我找到错误,在此先感谢!


阅读 791

收藏
2020-07-07

共1个答案

一尘不染

我认为您遇到了我刚刚遇到的同样问题。您可以拨打此电话。几个教程让您.comparePassword()从这样的模型中调用方法。

User.comparePassword(candidate, cb...)

这是行不通的,因为该方法位于上,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);
          }
        })
      })
    })
);

因此,我曾经findOne({})获取文档实例,然后不得不通过深入研究文档上的架构属性来访问架构方法
user.schema.methods.comparePassword

我注意到了几个区别:

  1. 我的是instance方法,而你的是static方法。我相信会有类似的方法访问策略。
  2. 我发现我必须将哈希传递给comparePassword()函数。也许这对静态变量不是必需的,但是我无法访问this.password
2020-07-07