typescriptlayoutnext.jshigher-order-components

Per-page layout for pages wrapped with HOC using TypeScript


I want to apply layout to a page like the below link:

layouts#per-page-layouts

But my page has a difference, it's wrapped with a HOC, so I applied getLayout to the higher order component itself like this:

PageWithAuth.getLayout

But it gives me this error:

enter image description here

The page looks like this:

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

const PageWithAuth = withAuth(TestPage);

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

export default PageWithAuth;

_app.tsx looks like this:

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 looks like this:

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

How to solve it?


Solution

  • You can explicitly type the return type of withAuth by extending React.FunctionComponent, and adding the getLayout property to it.

    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
    }