Next.js+TypeScript下扩展useSession用户属性的类型错误解决
在Next.js + TypeScript中扩展NextAuth useSession返回的用户对象类型
你遇到的问题核心是直接修改node_modules中的类型文件无法持久生效(依赖更新后会被覆盖),且不符合TypeScript的类型扩展规范。正确的做法是通过**模块扩展(Module Augmentation)**在项目内自定义NextAuth的类型,以下是完整解决方案:
1. 还原node_modules中的类型文件
直接修改node_modules/next-auth/src/core/types.ts是临时方案,npm install/yarn install后所有修改会被覆盖,必须完全还原这些文件。
2. 创建项目专属的NextAuth类型声明文件
在项目根目录(或src目录下)创建types/next-auth.d.ts文件,通过TypeScript的模块扩展功能覆盖NextAuth的内置类型:
import NextAuth from "next-auth"; // 扩展Session接口,添加自定义用户属性 declare module "next-auth" { interface Session { user: { id: string; iat: number; exp: number; jti: string; name?: string | null; email?: string | null; image?: string | null; }; } // 扩展User接口,匹配authorize返回的用户结构 interface User { id: string; token?: string; // 对应你authorize中返回的user.token name?: string | null; email?: string | null; image?: string | null; } } // 扩展JWT接口,确保token包含自定义属性 declare module "next-auth/jwt" { interface JWT { id: string; iat: number; exp: number; jti: string; user?: User; } }
3. 调整[...nextauth]中的回调逻辑
优化jwt和session回调,确保属性正确传递,同时利用扩展后的类型(无需手动类型断言):
// src/api/auth/[...nextauth].ts import NextAuth, { NextAuthOptions } from "next-auth"; import CredentialsProvider from "next-auth/providers/credentials"; import axios from "axios"; const nextAuthOptions: NextAuthOptions = { providers: [ CredentialsProvider({ name: "credentials", credentials: { email: { label: "email", type: "text" }, password: { label: "password", type: "password" }, }, async authorize(credentials, _) { const response = await axios.post( "http://localhost:4000/auth/login", { email: credentials?.email, password: credentials?.password, }, { headers: { "Content-type": "application/json" }, } ); const user = response.data.data; // 确保返回的user包含id和token if (user.id && user.token) { return user; } return null; }, }), ], pages: { signIn: "/sign-in2", }, callbacks: { async jwt({ token, user }) { // 当用户首次登录时,将user的id赋值给token if (user) { token.id = user.id; } // token本身自带iat、exp、jti属性,无需手动赋值 return token; }, async session({ session, token }) { // 将token中的属性同步到session.user session.user.id = token.id; session.user.iat = token.iat; session.user.exp = token.exp; session.user.jti = token.jti; return session; }, }, }; const handler = NextAuth(nextAuthOptions); export { handler as GET, handler as POST, nextAuthOptions };
4. 验证组件中的类型支持
在Cart组件中,useSession返回的data.user现在会自动识别新增的属性,TypeScript不再报错:
const handleFinishPurchaseClick = async () => { if (!data?.user) { return alert("Fazer o Login"); } // 此处data.user.id会被TypeScript正确识别为string类型 const order = await axios.post("http://localhost:4000/orders", { user_id: data.user.id, }); console.log(order); };
5. 确保TypeScript识别自定义类型
检查项目的tsconfig.json,确保include字段包含我们创建的类型文件:
{ "compilerOptions": { // 其他配置... }, "include": ["types/**/*.d.ts", "src/**/*"], "exclude": ["node_modules"] }
内容的提问来源于stack exchange,提问作者Renan França
相关产品推荐
相关产品推荐

