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
相关产品推荐
相关产品推荐

