NextJS v13.1.1:如何为layout.ts中的RootLayout组件添加类型?
使用Next.js 13 v13.1.1的App Router,layout.ts为必填文件。用TypeScript开发时,需为RootLayout组件的props添加类型,想确认Next.js是否声明/导出或隐含了RootLayout的props类型。
补充场景:通过next-auth实现社交登录,SessionProvider组件依赖Next.js会话功能。测试发现RootLayout的props中暴露了托管会话,可用于SessionProvider完成next-auth相关功能。
编写的代码在开发服务器运行正常,但构建时报错,提示RootLayoutProps类型无效,具体错误信息:
app/layout.tsx
Type error: Layout "app/layout.tsx" has an invalid "default" export:
Type "RootLayoutProps" is not valid.
ELIFECYCLE Command failed with exit code 1.
ERROR: command finished with error: command (absolute-path-to-root-of-next-project) pnpm run build exited (1)
开发代码如下:
RootLayout(app/layout.tsx)
import { ReactNode } from 'react'; import { Session } from 'next-auth'; import SessionInitializer from './SessionInitializer'; interface RootLayoutProps { children: ReactNode; session: undefined | null | Session; } export default function RootLayout(props: RootLayoutProps) { const { children, session } = props; return ( <html> <SessionInitializer session={session}> <div>{ children }</div> </SessionInitializer> </html> ) }
SessionInitializer(app/SessionInitializer.tsx)
"use client"; import { ReactNode } from 'react'; import { SessionProvider } from 'next-auth/react'; import { Session } from 'next-auth'; interface SessionInitializerProps { children: ReactNode; session: undefined | null | Session; } export default function SessionInitializer(props: SessionInitializerProps) { return ( <SessionProvider session={session}> { children } </SessionProvider> ) }
Next.js官方导出了App Router中Layout组件的基础类型,你需要基于官方类型扩展,而非完全自定义,这样才能通过构建校验。
正确的类型定义方式
- 从
next导入官方的LayoutProps类型,它包含Layout组件的基础必填props(仅children) - 通过交叉类型扩展,添加
session的类型(结合next-auth的Session类型)
修改后的RootLayout代码:
import { ReactNode } from 'react'; import { Session } from 'next-auth'; import type { LayoutProps } from 'next'; import SessionInitializer from './SessionInitializer'; // 基于官方LayoutProps扩展session类型 type RootLayoutProps = LayoutProps & { session: Session | null | undefined; }; export default function RootLayout({ children, session }: RootLayoutProps) { return ( <html> <SessionInitializer session={session}> <div>{children}</div> </SessionInitializer> </html> ); }
说明
- Next.js在构建阶段会严格校验Layout组件的props类型是否符合官方规范,直接自定义
RootLayoutProps会因为未继承官方基础类型导致报错 LayoutProps是Next.js为App Router Layout组件提供的标准类型,确保你的组件props结构符合框架要求- session类型结合next-auth的
Session定义,保证类型匹配next-auth的SessionProvider要求
内容的提问来源于stack exchange,提问作者imfromthefuture

