Mongoose预保存方法在express typescript中给出类型错误

thtygnil  于 2023-05-30  发布在  TypeScript
关注(0)|答案(1)|浏览(128)

我的堆栈是express js in typescript with mongoose。以下是我的模型:

import mongoose, { Schema, Document, Model } from 'mongoose';
import crypto from 'crypto';
import validator from 'validator';
import bcrypt from 'bcryptjs';
import roles from '../constant/role';

export interface IUser extends Document {
  firstName: string;
  lastName: string;
  phone: string;
  email: string;
  password: string;
  role: string;
  dateOfBirth?: Date;
  emailVerified?: boolean;
  phoneVerified?: boolean;
  updatedBy?: Schema.Types.ObjectId;
  createdBy?: Schema.Types.ObjectId;
  passwordChangedAt?: Date;
  passwordResetToken?: string;
  passwordResetExpires?: Date;
  emailVerificationToken?: string;
  emailVerificationExpires?: Date;
  active?: boolean;
  fullName?: string;
}

export interface IUserMethods {
  correctPassword(
    candidatePassword: string,
    userPassword: string
  ): Promise<boolean>;
  changedPasswordAfter(jwtTimeStamp: number): boolean;
  createPasswordResetToken(): string;
  createEmailVerificationToken(): string;
}

type UserModel = Model<IUser, {}, IUserMethods>;

const UserSchema = new Schema<IUser, UserModel, IUserMethods>(
  {
    firstName: {
      type: String,
      required: [true, 'First Name is required'],
      trim: true,
    },
    lastName: { type: String, trim: true },
    phone: {
      type: String,
      trim: true,
      unique: true,
      required: [true, 'Phone is required'],
    },
    email: {
      type: String,
      required: [true, 'Email is required'],
      unique: true,
      validate: [validator.isEmail, 'Email is not valid'],
      trim: true,
    },
    password: {
      type: String,
      required: [true, 'Password is required'],
      select: false,
    },
    dateOfBirth: { type: Date },
    emailVerified: { type: Boolean, default: false },
    phoneVerified: { type: Boolean, default: false },
    role: {
      type: String,
      enum: [roles.SUPER_ADMIN, roles.ADMIN, roles.STUDENT, roles.GUEST],
      default: roles.GUEST,
    },
    updatedBy: { type: Schema.Types.ObjectId, ref: 'User' },
    createdBy: { type: Schema.Types.ObjectId, ref: 'User' },
    passwordChangedAt: { type: Date },
    passwordResetToken: String,
    passwordResetExpires: Date,
    emailVerificationToken: String,
    emailVerificationExpires: Date,
    active: {
      type: Boolean,
      default: true,
      select: false,
    },
  },
  {
    timestamps: true,
    versionKey: false,
  }
);

UserSchema.pre(/^find/, async function (next) {
  const user = this;
  user.find({ active: { $ne: false } });
  next();
});

const User = mongoose.model<IUser, UserModel>('User', UserSchema);

export default User;

在vscode中,我在行中得到这个错误:user.find({ active: { $ne: false } });

Property 'find' does not exist on type '(Document<unknown, {}, FlatRecord<IUser>> & Omit<FlatRecord<IUser> & { _id: ObjectId; }, keyof IUserMethods> & IUserMethods) | Query<...>'.
  Property 'find' does not exist on type 'Document<unknown, {}, FlatRecord<IUser>> & Omit<FlatRecord<IUser> & { _id: ObjectId; }, keyof IUserMethods> & IUserMethods'.ts(2339)

不能弄清楚这里的问题是什么,为什么它说Document<unknown
有人能给我指个路吗?

cpjpxq1n

cpjpxq1n1#

我认为问题出在方式上,预勾是定义的。您将正则表达式/^find/作为第一个参数传递给pre,而不是字符串,这可能会导致它的行为不正确。
pre中间件期望第一个参数是string,有效值在这里列出。根据string的值,创建四种类型的中间件之一。
1.文档中间件。
1.查询中间件。
1.模型中间件。
1.聚合中间件。
在这些中间件中,this指的是不同的对象,如上面的链接所述。在您的例子中,它的默认值是Document Middleware,我相信,错误消息传达了这么多。所以你可以像这样更新你的钩子:

UserSchema.pre(/^find/, async function (next) {
  const user = this;
  user.model.find({ active: { $ne: false } });
  next();
});

或者传递一个有效的string而不是regex

相关问题