我已经使用以下内容定义了用户模式:

import mongoose from 'mongoose'
import { Model, Schema } from 'mongoose'
import bcrypt from 'bcrypt'

enum LoginType {
  EMAIL = 'email',
  GOOGLE = 'google',
}

interface IUser extends mongoose.Document {
  username: string
  email: string
  password: string
  loginTypes: LoginType
  comparePassword(password: string, callback: Function): Promise<Function>
}

interface IUserMethods extends Model<IUser> {
  comparePassword(password: string, callback: Function): Promise<Function>
}

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

const userSchema = new Schema<IUser, UserModel, IUserMethods>({
  username: {
    type: String,
    required: true,
  },
  email: {
    type: String,
    required: true,
  },
  password: {
    type: String,
    require: true,
  },
  loginTypes: {
    type: String,
    require: true,
    enum: Object.values(LoginType),
  },
})

/* callback = (err: Error, isMatch: any) => {} */
userSchema.methods.comparePassword = async function (
  password: string,
  callback: Function
): Promise<Function> {
  let result
  try {
    result = await bcrypt.compare(password, this.password)
    return callback(null, result)
  } catch (err) {
    return callback(err, result)
  }
}

export default mongoose.model<IUser>('User', userSchema)

并在登录路径中调用它,但TypeScrip在foundUser.comparePassword(req.body.password, (err: Error, isMatch: any) => {})上显示错误Property 'comparePassword' does not exist on type '() => Promise<(Document<unknown, {}, IUser> & Omit<IUser & { _id: ObjectId; }, never>) | null>'.

以下是我的登录路由:

router.post('/credentials', (req, res) => {
  /* Check if user exists in database */
  const foundUser = async () => await User.findOne({ email: req.body.email })

  if (!foundUser) {
    res.status(401).send({ message: 'User does not exist' })
  }

  /* Check if password matches */
  foundUser.comparePassword(req.body.password, (err: Error, isMatch: any) => {})

  const jwt_token = jwt.sign(
    { name: req.body.name, email: req.body.email, id: req.body.id },
    JWT_SECRET,
    { expiresIn: '10000' }
  )
  res.status(200).send({
    name: req.body.name,
    email: req.body.email,
    id: req.body.id,
    jwt_token: jwt_token,
  })
})

I've search for it and try this solution before but not working.
While, I found

const a = new User({})
a.comparePassword(req.body.password, (err: Error, isMatch: any) => {})

就像mongoose doctor 说的那样,我可以正常工作,但如果我先用findOne再拨打comparePassword,那就不行了

推荐答案

在这条线上:

const foundUser = async () => await User.findOne({ email: req.body.email })

您正在定义一个名为foundUserfunction,当被调用时将返回await User.findOne({ email: req.body.email })的结果.

如所编写的,您需要调用函数foundUser来实际查询MongoDB.类似于:

const foundUser = async () => await User.findOne({ email: req.body.email })
const user = await foundUser();

但我认为你的意图是这样的:

const foundUser = await User.findOne({ email: req.body.email })

这里foundUser不是一个函数,它是MongoDB查询的结果.

Node.js相关问答推荐

错误:找不到模块';/var/apps/前端/bash';

在Android Studio中react 本机构建失败:未正确检测到Node.js版本

一个函数中的两个依赖的NodeJS数据库操作.如果第二个失败了怎么办?

下一个API路由如何处理多个并发请求?

如何使用NodeJS在mongodb中更新文档

Next.js 在我的电脑上没有构建错误,但它们在使用 Vercel 部署时发生

从 Response.json() 返回的 JSON 似乎无效?

将代码转换为 ES6 Discord.js 的问题

如何使用 NodeJS 加密模块将 ECDH 密钥转换为 PEM 格式

Fly.io 启动问题:无法从源获取图像或构建错误:构建错误:连接期间出错:发布...

错误:找不到模块'C:\Users\nguye\AppData\Local\nodejs\node_modules\npm\bin\npm-cli.js'

Express.js - 监听请求中止

更新文档数组中的文档 Mongoose

nuxt:在 docker 镜像中找不到

NestJS 共享模块的问题

使用加密模块的流功能获取文件的哈希(即:没有 hash.update 和 hash.digest)

为当前目录提供服务的简单文件服务器

如何从 Redis 保存和检索会话

Nodejs续集批量更新

避免在弹性 beantalk 中重建 node_modules