Next.js部署Vercel遇Page导出类型错误,本地正常求解决
问题分析与解决方案
核心问题
你遇到的类型错误根源是Next.js App Router的page.tsx页面组件有固定的props类型规则:
- 页面组件(Server Component)默认仅能接收
params和searchParams作为顶层props,不能自定义info、exp这类非标准props。 - 你的代码里定义了
FormProps并让AdminAbout组件接收这两个props,违反了Next.js页面组件规范,导致Vercel部署时类型校验失败(本地可能因类型校验宽松未触发报错)。
另外,组件内部已经通过Prisma查询了完整数据,但传给子组件的却是外部传入的未定义props,逻辑上存在冗余。
修复步骤
- 移除自定义的
FormProps,让页面组件遵循Next.js默认的页面props规则(如果不需要params/searchParams,可直接不接收)。 - 调整子组件传参逻辑:使用组件内部查询到的数据传给子组件,而非外部未定义的props。
修改后的代码示例
import prisma from '@/lib/prisma'; // 确保正确导入Prisma客户端 const AdminAbout = async () => { // 不再接收自定义props const infos = await prisma.info.findMany(); const experiences = await prisma.experience.findMany(); // 根据业务逻辑,取查询结果的第一条作为表单默认值(如果是新增表单可省略) const currentInfo = infos[0]; const currentExp = experiences[0]; return ( <div> <div className="max-w-7xl px-10 mx-auto space-y-5 md:ml-[17rem] pt-20 min-h-screen"> <div className=" flex items-center space-x-2 mb-2 shadow-md rounded-lg bg-primary p-4"> <h1 className="font-bold pl-5 text-primary-foreground"> Description Form </h1> </div> {/* 传入查询到的数据,而非外部props */} {currentInfo && <InfoForm info={currentInfo} />} <Table> <TableCaption>Description Form</TableCaption> <TableHeader> <TableRow> <TableHead className="w-[100px]">Resume</TableHead> <TableHead>Description</TableHead> <TableHead className="text-right">Action</TableHead> </TableRow> </TableHeader> <TableBody> {infos.map((info) => ( <TableRow key={info.id}> {info.public_id && ( <TableCell className="font-medium"> <CldImage className="aspect-video" width={100} height={100} src={info.public_id} alt="pdf" /> </TableCell> )} <TableCell className="font-medium"> {info.description.length > 50 ? `${info.description.substring(0, 50)}...` : info.description} </TableCell> <TableCell className="font-medium"> <EditInfoForm info={info} /> </TableCell> <TableCell className="font-medium"> <DeleteInfoButton id={info.id} /> </TableCell> </TableRow> ))} </TableBody> </Table> {/* EXPERIENCE TABLE */} <div className=" flex items-center shadow-md rounded-lg bg-primary p-4 "> <h1 className="font-bold pl-5 text-primary-foreground"> Experience Form </h1> </div> {/* 传入查询到的数据,而非外部props */} {currentExp && <ExperienceForm exp={currentExp} />} <Table> <TableCaption>Experience Form</TableCaption> <TableHeader> <TableRow> <TableHead className="w-[100px]">Job Title</TableHead> <TableHead>Company</TableHead> <TableHead>Year</TableHead> <TableHead className="text-right">Action</TableHead> </TableRow> </TableHeader> <TableBody> {experiences.map((experience) => ( <TableRow key={experience.id}> <TableCell className="font-medium"> {experience.jobtitle} </TableCell> <TableCell>{experience.company}</TableCell> <TableCell> {experience.year.toLocaleString("default", { month: "long" })} {" "} {experience.year.getFullYear()} </TableCell> <TableCell className="text-right"> <EditExperienceForm exp={experience} /> </TableCell> <TableCell className="text-right"> <DeleteExperienceButton id={experience.id} /> </TableCell> </TableRow> ))} </TableBody> </Table> </div> </div> ); } export default AdminAbout
额外说明
- 如果
InfoForm/ExperienceForm是用于新增数据,而非编辑现有数据,可直接渲染表单,无需传入info/expprops,提交时再写入数据库。 - 确保Vercel部署时已配置好数据库环境变量,Prisma客户端能正常连接数据库。
内容的提问来源于stack exchange,提问作者Akinola
相关产品推荐
相关产品推荐

