You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js14集成NextAuth遇TS类型错误:string|undefined无法赋值

Next.js 14 + NextAuth 凭证登录 TypeScript 类型错误解决

问题场景

在Next.js 14项目中集成NextAuth实现凭证登录,对比用户输入密码与数据库存储密码时,遇到TypeScript类型错误:

"Argument of type 'string | undefined' is not assignable to parameter of type 'string | Buffer'."

错误触发代码行:

const passwordOk = existingUser && bcrypt.compareSync(password, existingUser.password)

完整配置代码如下:

import CredentialsProvider from "next-auth/providers/credentials"
import type { NextAuthOptions } from "next-auth"
import connectMongoDB from "@/lib/mongodb"
import bcrypt from "bcrypt"
import User from "@/models/user"

export const authOptions: NextAuthOptions = {
  providers: [
    CredentialsProvider({
      name: "Credentials",
      credentials: {
        email: {},
        password: {},
      },
      async authorize(credentials, req) {
        const email = credentials?.email
        const password = credentials?.password
        await connectMongoDB()
        const existingUser = await User.findOne({ email })
        const passwordOk =
          existingUser && bcrypt.compareSync(password, existingUser.password)

        if (passwordOk) {
          return existingUser
        } else {
          return null
        }
      },
    }),
  ],
}

错误原因

credentials?.password使用了可选链操作符,导致password的类型为string | undefined,而bcrypt.compareSync的第一个参数要求是string | Buffer,不允许传入undefined,TypeScript严格类型检查下就会抛出错误。

你尝试手动指定const password: string | Buffer = credentials?.password无效,是因为credentials?.password可能为undefined,无法直接赋值给不包含undefined的类型。

解决方案

方案1:提前校验参数(推荐)

在逻辑开始处先校验credentials及其中的email、password是否存在,提前返回null或抛出错误,确保后续变量类型确定:

async authorize(credentials, req) {
  // 提前校验参数完整性
  if (!credentials?.email || !credentials?.password) {
    return null; // 也可抛出错误:throw new Error("请输入邮箱和密码")
  }
  // 此时email和password都是确定的string类型
  const email = credentials.email;
  const password = credentials.password;

  await connectMongoDB()
  const existingUser = await User.findOne({ email })
  
  const passwordOk = existingUser && bcrypt.compareSync(password, existingUser.password)

  if (passwordOk) {
    return existingUser
  } else {
    return null
  }
},

方案2:短路求值判断(你尝试的方法)

通过password &&的短路判断,确保只有当password存在时才执行compareSync,避免传入undefined:

const passwordOk =
  existingUser &&
  password &&
  bcrypt.compareSync(password, existingUser.password)

这种方法能消除类型错误,是可行的,但提前校验参数的方式代码可读性更强,也能更早拦截无效请求。


内容的提问来源于stack exchange,提问作者Muhammad Rabi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 06:42:36