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

Auth.js v5 signIn选项返回类型为never的错误求助

解决Auth.js v5中signIn设置redirect:false后类型为never的问题

问题原因

当在Auth.js v5的signIn方法中设置redirect: false时,TypeScript可能无法正确推断返回值类型,导致signIndata被推断为never,进而无法访问error属性。这通常是因为类型推断限制,或是参数传递时使用模糊的any类型导致的。

解决方案

1. 明确参数与返回值类型

避免使用any定义登录数据,手动指定signIn的返回类型,让TypeScript正确识别返回结构:

'use server'
import { signIn } from "@/auth"

// 定义登录数据的强类型
type LoginCredentials = {
  email: string;
  password: string;
}

export const SignIn = async (credentials: LoginCredentials) => {
  // 直接传递参数并明确redirect为false
  const signInResult = await signIn("credentials", {
    ...credentials,
    redirect: false,
  }) as { error?: string } | null;

  if (signInResult?.error) {
    console.log(signInResult.error);
    // 返回错误信息给前端处理
    return { success: false, error: signInResult.error };
  } else {
    // 返回成功标识,前端收到后执行跳转
    return { success: true };
  }
}

2. 确保Credentials Provider配置正确

在Auth.js的配置文件(如app/auth.ts)中,保证credentials provider的authorize函数逻辑正确,返回值符合预期:

import NextAuth from "next-auth";
import Credentials from "next-auth/providers/credentials";

export const { handlers, auth, signIn, signOut } = NextAuth({
  providers: [
    Credentials({
      credentials: {
        email: { label: "邮箱", type: "email" },
        password: { label: "密码", type: "password" },
      },
      async authorize(credentials) {
        // 验证credentials是否存在
        if (!credentials?.email || !credentials?.password) {
          return null;
        }

        // 替换为你的真实验证逻辑(比如查询数据库)
        const isValid = credentials.password === "your-password";
        if (!isValid) {
          // 验证失败返回null,signIn会返回默认错误"CredentialsSignin"
          // 若需自定义错误,可抛出Error:
          // throw new Error("邮箱或密码错误");
          return null;
        }

        // 验证成功返回用户对象
        return { id: "1", email: credentials.email };
      },
    }),
  ],
});

3. 前端调用逻辑调整

在客户端组件中调用服务端Action,根据返回结果执行跳转:

'use client'
import { useRouter } from 'next/navigation';
import { SignIn } from '@/actions/auth'; // 替换为你的服务端Action路径

export default function LoginForm() {
  const router = useRouter();

  const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    const formData = new FormData(e.currentTarget);
    const credentials = {
      email: formData.get('email') as string,
      password: formData.get('password') as string,
    };

    const result = await SignIn(credentials);
    if (result.success) {
      router.push('/admin');
    } else {
      // 显示错误提示(比如Toast)
      alert(result.error);
    }
  };

  return (
    <form onSubmit={handleSubmit} className="space-y-4">
      <div>
        <label htmlFor="email">邮箱</label>
        <input type="email" id="email" name="email" required />
      </div>
      <div>
        <label htmlFor="password">密码</label>
        <input type="password" id="password" name="password" required />
      </div>
      <button type="submit">登录</button>
    </form>
  );
}

关键说明

  • 当authorize返回null时,signIn在redirect:false模式下会返回{ error: "CredentialsSignin" };若在authorize中抛出自定义错误,signIn会返回包含该错误信息的对象。
  • 使用强类型替代any可以帮助TypeScript正确推断类型,避免never类型问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 07:01:03