admin管理员组

文章数量:1277391

I am trying to follow the next-auth documentation using TypeScript. Using the following code and some code in _app.tsx from the docs I can protect a page:

AdminDashboard.auth = {
  role: "admin",
  loading: <AdminLoadingSkeleton />,
  unauthorized: "/login-with-different-user", // redirect to this url
}

What is the right way to implement this using TypeScript?

I found a solution which works, but I am not sure if this is the right way:

export type NextPageWithAuth = NextPage & {
  auth: boolean,
  role: string
}

type NextPageAuthProps = {
  Component: NextPageWithAuth,
  pageProps: any
}

The AppProps type is quite more sophisticated than my own NextPageAuthProps.

I am trying to follow the next-auth documentation using TypeScript. Using the following code and some code in _app.tsx from the docs I can protect a page:

AdminDashboard.auth = {
  role: "admin",
  loading: <AdminLoadingSkeleton />,
  unauthorized: "/login-with-different-user", // redirect to this url
}

What is the right way to implement this using TypeScript?

I found a solution which works, but I am not sure if this is the right way:

export type NextPageWithAuth = NextPage & {
  auth: boolean,
  role: string
}

type NextPageAuthProps = {
  Component: NextPageWithAuth,
  pageProps: any
}

The AppProps type is quite more sophisticated than my own NextPageAuthProps.

Share Improve this question edited Nov 15, 2021 at 8:34 juliomalves 50.4k23 gold badges177 silver badges168 bronze badges asked Nov 14, 2021 at 18:10 schgabschgab 6667 silver badges21 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 13

In the page, you can extend the built-in NextPage type to include the auth field with the appropriate type.

import type { NextPage } from 'next';

type PageAuth = {
  role: string
  loading: JSX.Element
  unauthorized: string
};

export type NextPageWithAuth<P = {}, IP = P> = NextPage<P, IP> & {
  auth: PageAuth
};

const AdminDashboard: NextPageWithAuth = () => {
  // Your `AdminDashboard` code here
};

AdminDashboard.auth = {
  role: "admin",
  loading: <AdminLoadingSkeleton />,
  unauthorized: "/login-with-different-user"
};

export default AdminDashboard;

Then, in the custom _app, you can extend AppProps so that the Component prop extends the type you declared in the page.

import type { NextComponentType, NextPageContext } from 'next';
import type { NextPageWithAuth } from '<path-to>/AdminDashboard';

type NextComponentWithAuth = NextComponentType<NextPageContext, any, {}> & Partial<NextPageWithAuth>

type ExtendedAppProps<P = {}> = AppProps<P> & {
  Component: NextComponentWithAuth
};

function MyApp({ Component, pageProps }: ExtendedAppProps) {
   //...
}

The accepted answer's type definitions hurt my head, so I solved the issue by calling getStaticProps with an auth property on the pages I wanted to protect:

// bottom of page I want to protect..

export const getStaticProps = async () => {
  return {
    props: { auth: true },
  };
};

and then consuming the prop in _app.tsx like so:

const MyApp: AppType<{ session: Session | null, auth: boolean }> = ({
  Component,
  pageProps: { session, ...pageProps },
}) => {

  const { auth } = pageProps

  return (
    <SessionProvider session={session} refetchOnWindowFocus={false}>
      <NavBar />
      {auth ? (
        <RouteGuard>
          <Component {...pageProps} />
        </RouteGuard>
      ) : (
        <Component {...pageProps} />  
      )}
      <ReactQueryDevtools />
      <MobileFooter />
    </SessionProvider>
  );
};

本文标签: javascriptHow to extend NextPage type to add custom field to page componentStack Overflow