Next.js构建报错:getStaticPaths与App Router不兼容修复请求
问题描述
本地运行Next.js项目无异常,但执行npm run build时抛出类型错误:Type 'OmitWithTag<...>'不满足约束'{ [x: string]: never; }',提示getStaticPaths属性与索引签名不兼容。
原代码
export default async function Product({ params, }: { params: { slug: string | undefined }; }) { // uri to get single Product from backend const filteredData = pagedata.filter((elem) => elem.title == params.slug); const pageElems = filteredData[0].content.map((elem) => { return ( <div key={elem.title} className={`${satoshi.className} inner-elements-company-page`} id={elem.title.replaceAll(" ", "_")} > <h3>{elem.title}</h3> <p>{elem.desc}</p> </div> ); }); return ( <> <Header /> <div className="total-company-page-component"> <div className="total-company-heading-container"> <h1 className={integralCFBold.className}>{params.slug}</h1> </div> <div className="total-company-details-container">{pageElems}</div> </div> <Footer /> </> ); } export async function getStaticPaths() { const paths = pagedata.map((Elem: { title: { toString: () => any } }) => { return { params: { slug: Elem.title.toString(), }, }; }); return { paths, fallback: false, }; }
错误信息
Type error: Type 'OmitWithTag<typeof import("D:/Fullstack/e-commerce/frontend-copy/src/app/footer/[slug]/page"), "metadata" | "default" | "config" | "generateStaticParams" | "revalidate" | "dynamic" | "dynamicParams" | ... 4 more ... | "generateMetadata", "">' does not satisfy the constraint '{ [x: string]: never; }'.
Property 'getStaticPaths' is incompatible with index signature.
Type '() => Promise<{ paths: { params: { slug: any; }; }[]; fallback: boolean; }>' is not assignable to type 'never'.
修复方案
你使用的是Next.js App Router(文件路径位于src/app/下),但getStaticPaths是Pages Router专属的API,App Router中生成静态路径需使用generateStaticParams替代getStaticPaths,这是导致类型不兼容的核心原因。
修改步骤
- 替换
getStaticPaths为generateStaticParams - 调整返回格式:无需包裹
paths和fallback字段,直接返回参数数组 - 优化
params参数类型(可选,提升类型安全性)
修改后的代码
// 按需调整组件、字体的导入路径 import { Header, Footer } from '../components'; import satoshi from '../fonts/satoshi'; import integralCFBold from '../fonts/integral-cf-bold'; // 为pagedata定义类型(可选,推荐添加以避免隐式any) type PageContent = { title: string; desc: string; }; type PageDataItem = { title: string; content: PageContent[]; }; declare const pagedata: PageDataItem[]; export default async function Product({ params, }: { params: { slug: string }; // App Router中generateStaticParams生成的slug不会为undefined,可移除该类型 }) { const filteredData = pagedata.filter((elem) => elem.title === params.slug); // 处理数据不存在的边界情况,避免filteredData[0]报错 if (!filteredData.length) { return <div>页面不存在</div>; } const pageElems = filteredData[0].content.map((elem) => { return ( <div key={elem.title} className={`${satoshi.className} inner-elements-company-page`} id={elem.title.replaceAll(" ", "_")} > <h3>{elem.title}</h3> <p>{elem.desc}</p> </div> ); }); return ( <> <Header /> <div className="total-company-page-component"> <div className="total-company-heading-container"> <h1 className={integralCFBold.className}>{params.slug}</h1> </div> <div className="total-company-details-container">{pageElems}</div> </div> <Footer /> </> ); } // 用generateStaticParams替代getStaticPaths export async function generateStaticParams() { return pagedata.map((item) => ({ slug: item.title, })); }
额外说明
- App Router中
generateStaticParams默认按fallback: false生成静态路径,如需开启增量静态生成,可在页面配置dynamicParams: true - 移除
params.slug的| undefined类型:因为generateStaticParams生成的路径均为合法slug,不会出现undefined的情况 - 添加类型定义可避免隐式any,增强代码健壮性
内容的提问来源于stack exchange,提问作者Manideep Vaddepalli

