Next.js14/Next-auth5 Session类型未更新,TS提示user不存在
解决Next-auth中TypeScript提示“Property 'user' does not exist on type 'Session | null'”问题
问题根源
你遇到的问题主要来自两个方面:
- Next-auth的TypeScript模块扩展未被正确合并
auth()函数可能返回null(未登录状态),直接解构user会触发类型检查错误
解决方案
1. 合并Next-auth的模块声明
将auth.ts中分开的两个declare module "next-auth"合并为一个,确保TypeScript能正确识别接口扩展:
import NextAuth from "next-auth"; import CredentialsProvider from "next-auth/providers/credentials"; import { authConfig } from "./authconfig"; import { connectDb } from "./lib/utils"; import { User } from "./lib/models"; import bcrypt from "bcrypt"; import { UserType } from "./lib/types"; // 合并模块声明,确保接口扩展生效 declare module "next-auth" { interface Session { user?: UserType; } interface User { username: string; img: string; } } const login = async (credentials: Partial<Record<string, unknown>>) => { try { connectDb(); const user = await User.findOne({ username: credentials.username }); if (!user) throw new Error("Invalid credentials"); const isPasswordCorrect = await bcrypt.compare( credentials.password as string, user.password ); if (!isPasswordCorrect) throw new Error("Invalid credentials"); return user; } catch (error) { console.log(error); throw new Error("Login failed"); } }; export const { signIn, signOut, auth } = NextAuth({ ...authConfig, providers: [ CredentialsProvider({ async authorize(credentials) { try { const user = await login(credentials); return user; } catch (error) { return null; } }, }), ], callbacks: { async session({ session, user }) { // 优化赋值逻辑,避免依赖原session.user存在 session.user = { ...session.user, username: user.username, img: user.img, } as UserType; return session; }, }, });
2. 处理auth()返回的null情况
在Sidebar组件中,auth()可能返回null(用户未登录时),需先判断session是否存在再获取user:
import { MdLogout } from "react-icons/md"; import styles from "./sidebar.module.scss"; import MenuLink from "./menuLink/menuLink"; import Image from "next/image"; import { MENU_ITEMS } from "@/app/data/menuItems"; import { auth, signOut } from "@/app/auth"; const Sidebar = async () => { const session = await auth(); // 先确认session存在,再提取user const user = session?.user; return ( <div className={styles.container}> <div className={styles.user}> <Image className={styles.userImage} priority src={user?.img || "/noavatar.png"} alt="" width="50" height="50" /> <div className={styles.userDetail}> <span className={styles.username}>{user?.username}</span> <span className={styles.userTitle}>Administrator</span> </div> </div> <ul className={styles.list}> {MENU_ITEMS.map((category) => ( <li key={category.title}> <span className={styles.category}>{category.title}</span> {category.list.map((item) => ( <MenuLink item={item} key={item.title} /> ))} </li> ))} </ul> <form action={async () => { "use server"; await signOut(); }} > <button className={styles.logout}> <MdLogout /> Log out </button> </form> </div> ); }; export default Sidebar;
3. 额外检查:确保UserType类型匹配
确认你的UserType类型和扩展的User接口结构一致,例如:
// ./lib/types.ts export type UserType = { id?: string; username: string; img: string; // 其他业务所需字段 };
关键说明
- TypeScript要求同一模块的声明必须合并,分开写会导致扩展失效
auth()函数返回类型为Session | null,必须处理null情况才能安全访问user- 优化session回调逻辑,避免依赖默认
session.user的存在,确保自定义字段正确赋值
内容的提问来源于stack exchange,提问作者CzechCoder
相关产品推荐
相关产品推荐

