You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为页面组件分配扩展NextPage类型时遭遇Type Error求助

解决Next.js中NextPageWithLayout与带Props组件的类型不兼容问题

问题

在galleryssr.tsx的const Page处出现类型错误,引入getServerSideProps传递props前,getLayout功能正常,报错提示NextPageWithLayout无法兼容当前组件类型,需调整类型定义以支持props。

错误详情

Type '{ (props: Props): JSX.Element; getLayout(page: ReactElement<any, string | JSXElementConstructor<any>>): JSX.Element; }' is not assignable to type 'NextPageWithLayout'.
  Type '{ (props: Props): JSX.Element; getLayout(page: ReactElement<any, string | JSXElementConstructor<any>>): JSX.Element; }' is not assignable to type 'FunctionComponent<{}> & { getInitialProps?(context: NextPageContext): {} | Promise<{}>; } & { getLayout?: ((page: ReactElement<any, string | JSXElementConstructor<...>>) => ReactNode) | undefined; }'.
    Type '{ (props: Props): JSX.Element; getLayout(page: ReactElement<any, string | JSXElementConstructor<any>>): JSX.Element; }' is not assignable to type 'FunctionComponent<{}>'.
      Types of parameters 'props' and 'props' are incompatible.
        Property 'pictures' is missing in type '{}' but required in type 'Props'.ts(2322)
galleryssr.tsx(19, 3): 'pictures' is declared here.

相关代码

_app.tsx中的类型定义

export type NextPageWithLayout = NextPage & {
  getLayout?: (page: ReactElement) => ReactNode;
};

type AppPropsWithLayout = AppProps & {
  Component: NextPageWithLayout;
};

function MyApp({ Component, pageProps }: AppPropsWithLayout) {
  const getLayout = Component.getLayout ?? ((page) => page);

  return (
      <ThemeContextProvider>
          {getLayout(<Component {...pageProps} />)}
      </ThemeContextProvider>
  );
}

export default MyApp;

galleryssr.tsx页面代码

import type { ReactElement } from "react";
import { SidebarLayout } from "../layouts/SidebarLayout";
import type { NextPageWithLayout } from "./_app";
import Image from "next/image";
import { GetServerSideProps } from "next";

type Picture = {
  id: string;
  author: string;
  width: number;
  height: number;
  url: string;
  download_url: string;
};

type Props = {
  pictures: Picture[];
};

const Page: NextPageWithLayout = (props: Props) => {
  return (
    <div className="w-full text-left">
      <h1>This is a server side rendered gallery</h1>
      <div className="grid grid-cols-1 grid-gap-4">
        {props.pictures.map((picture) => {
          return (
            <div
              className="flex flex-col items-center justify-center bg-base-200 p-4 rounded-md my-4"
              key={picture.id}
            >
              <div className="h-[300px] w-[300px] relative">
                <Image
                  src={picture.download_url}
                  alt={picture.id}
                  layout="fill"
                  objectFit="contain"
                  width={picture.width / 20}
                  height={picture.height / 20}
                />
              </div>

              <div>{picture.author}</div>
            </div>
          );
        })}
      </div>
    </div>
  );
};

Page.getLayout = function getLayout(page: ReactElement) {
  return <SidebarLayout>{page}</SidebarLayout>;
};

export const getServerSideProps: GetServerSideProps = async () => {
  const res = await fetch(`https://picsum.photos/v2/list`);
  const pictures = await res.json();
  return { props: { pictures } };
};

export default Page;

解决方案

问题根源是NextPageWithLayout未支持泛型,无法关联页面组件的Props类型。需修改类型定义并在页面中传入对应Props类型:

1. 修改_app.tsx中的类型定义

让NextPageWithLayout支持泛型,继承NextPage的泛型能力:

// _app.tsx
import type { NextPage, AppProps } from 'next';
import type { ReactElement, ReactNode } from 'react';

export type NextPageWithLayout<P = {}> = NextPage<P> & {
  getLayout?: (page: ReactElement) => ReactNode;
};

type AppPropsWithLayout = AppProps & {
  Component: NextPageWithLayout;
};

// 其余代码保持不变
function MyApp({ Component, pageProps }: AppPropsWithLayout) {
  const getLayout = Component.getLayout ?? ((page) => page);

  return (
      <ThemeContextProvider>
          {getLayout(<Component {...pageProps} />)}
      </ThemeContextProvider>
  );
}

export default MyApp;

2. 更新galleryssr.tsx的页面类型声明

给NextPageWithLayout传入页面的Props类型:

// galleryssr.tsx中修改Page的类型声明
const Page: NextPageWithLayout<Props> = (props: Props) => {
  // 组件内容保持不变
};

修改完成后,TypeScript即可正确识别页面组件的Props类型,解决类型不兼容问题。

内容的提问来源于stack exchange,提问作者user12457151

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 21:11:26