使用 TypeScript 使用 HOC 包装的页面的每页布局

Per-page layout for pages wrapped with HOC using TypeScript

我想将布局应用到如下页面 link:

layouts#per-page-layouts

但我的页面有所不同,它用 HOC 包装,所以我将 getLayout 应用于高阶组件本身,如下所示:

PageWithAuth.getLayout

但是它给我这个错误:

页面如下所示:

function TestPage() {
  return {
    /** Your content */
  }
}

const PageWithAuth = withAuth(TestPage);

PageWithAuth.getLayout = function getLayout(page: ReactElement) {
  return (
      <Layout>{page}</Layout>
  )
}

export default PageWithAuth;

_app.tsx 看起来像这样:

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

type AppPropsWithLayout = AppProps & {
  Component: NextPageWithLayout
}

export default function MyApp({ Component, pageProps }: AppPropsWithLayout) {
  // Use the layout defined at the page level, if available
  const getLayout = Component.getLayout ?? ((page) => page)

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

HOC 看起来像这样:

export function withAuth<P>(WrappedComponent: React.ComponentType<P>) {
  const ComponentWithAuth = (props: P) => {
    return <WrappedComponent {...props} />;
  };
  return ComponentWithAuth;
}

如何解决?

您可以通过扩展 React.FunctionComponent 并向其添加 getLayout 属性 来显式键入 withAuth 的 return 类型。

type WithAuthComponent<P> = React.FunctionComponent<P> & {
    getLayout?: (page: React.ReactElement) => React.ReactNode
}

export function withAuth<P = {}>(WrappedComponent: React.ComponentType<P>): WithAuthComponent<P> {
    const ComponentWithAuth = (props: P) => {
        // Your auth logic
        return <WrappedComponent {...props} />;
    }
    return ComponentWithAuth
}