使用TypeScript开发NextAuth认证系统时遇到user.id类型不兼容问题求助
使用TypeScript开发NextAuth认证系统时遇到user.id类型不兼容问题求助
我刚梳理了你的问题——你在基于TypeScript的NextAuth认证系统中,明明所有代码里id都是number类型,却还是在callbacks部分触发了Type 'string' is not assignable to type 'number'的类型不兼容错误。下面帮你分析问题根源并给出解决方案:
问题根源拆解
- 重复类型定义导致冲突:你在
nextauth.ts文件和next-auth-extensions文件里各定义了一个CustomUser,这会让TypeScript的类型推断混乱,无法明确使用哪套类型规则。 - 默认类型未被完全覆盖:NextAuth原生的
DefaultUser、JWT类型中id是string类型,你的自定义类型虽然试图覆盖,但定义方式不够严谨,没能完全替换默认类型的影响。 - 回调参数类型推断偏差:
jwt和session回调的参数默认沿用NextAuth原生类型,没有正确关联到你的自定义类型,导致类型校验出错。
分步解决方案
1. 清理重复的类型定义
删除nextauth.ts文件中的CustomUser定义,所有类型扩展统一放到next-auth-extensions文件中,避免类型冲突。
2. 修正NextAuth类型扩展
调整你的类型扩展代码,确保完全覆盖原生类型,同时移除不安全的字段:
// next-auth-extensions.ts import { DefaultUser, DefaultSession, DefaultJWT } from "next-auth"; // 自定义User类型,覆盖原生id为number declare module "next-auth" { interface User extends Omit<DefaultUser, "id"> { id: number; badgeNumber: string; passwordHash: string; department: number; rank: number; admin?: boolean; superadmin?: boolean; name: string; createdPassword: boolean; } // 自定义Session类型,确保user字段完全匹配自定义User类型 interface Session extends DefaultSession { user: User; } } // 自定义JWT类型,注意不要存储密码哈希这类敏感字段 declare module "next-auth/jwt" { interface JWT extends Omit<DefaultJWT, "id"> { id: number; badgeNumber: string; department: number; rank: number; admin?: boolean; superadmin?: boolean; name: string; createdPassword: boolean; } }
3. 修正回调函数的类型关联
在nextauth.ts中明确指定回调参数的自定义类型,让TypeScript正确识别:
// nextauth.ts import type { NextAuthOptions, Session, JWT, User } from "next-auth"; // 引入类型扩展文件,确保TypeScript能加载自定义规则 import "./path/to/next-auth-extensions"; export const authOptions: NextAuthOptions = { // 保留你的providers、pages、secret、jwt、session等配置 callbacks: { async session({ session, token }: { session: Session; token: JWT }) { if (session.user) { // 此时token.id已经是number类型,无需额外转换 session.user.id = token.id; session.user.badgeNumber = token.badgeNumber; session.user.department = token.department; session.user.rank = token.rank; session.user.admin = token.admin; session.user.superadmin = token.superadmin; session.user.name = token.name; session.user.createdPassword = token.createdPassword; } return session; }, async jwt({ token, user }: { token: JWT; user?: User }) { if (user) { // user是自定义的User类型,id为number,直接赋值即可 token.id = user.id; token.badgeNumber = user.badgeNumber; token.department = user.department; token.rank = user.rank; token.admin = user.admin; token.superadmin = user.superadmin; token.name = user.name; token.createdPassword = user.createdPassword; } console.log(token); return token; }, }, }; const handler = NextAuth(authOptions); export { handler as GET, handler as POST };
4. 确认Prisma模型的类型匹配
检查你的Prisma Schema中User模型的id字段是否为Int类型,确保Prisma返回的用户对象id和自定义的number类型完全匹配。
最后验证
修改完成后重启开发服务器,让TypeScript重新加载类型定义,这时候应该就能解决user.id的类型不兼容问题了。
备注:内容来源于stack exchange,提问作者Ali AKCAN
相关产品推荐
相关产品推荐

