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

使用TypeScript开发NextAuth认证系统时遇到user.id类型不兼容问题求助

使用TypeScript开发NextAuth认证系统时遇到user.id类型不兼容问题求助

我刚梳理了你的问题——你在基于TypeScript的NextAuth认证系统中,明明所有代码里id都是number类型,却还是在callbacks部分触发了Type 'string' is not assignable to type 'number'的类型不兼容错误。下面帮你分析问题根源并给出解决方案:

问题根源拆解

  1. 重复类型定义导致冲突:你在nextauth.ts文件和next-auth-extensions文件里各定义了一个CustomUser,这会让TypeScript的类型推断混乱,无法明确使用哪套类型规则。
  2. 默认类型未被完全覆盖:NextAuth原生的DefaultUser、JWT类型中id是string类型,你的自定义类型虽然试图覆盖,但定义方式不够严谨,没能完全替换默认类型的影响。
  3. 回调参数类型推断偏差: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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.20 13:04:34