Каким типом TypeScript должны быть компонент NextJS _app.tsx и pageProps?

#javascript #reactjs #typescript #next.js

#javascript #reactjs #typescript #next.js

Вопрос:

Вот _app.tsx по умолчанию из NextJS:

 function MyApp({ Component, pageProps }) {
  return (
    <Component {...pageProps} />
  )
}
  

Проблема в том, что как только вы переключаетесь на TypeScript, вы получаете предупреждение в ES6Lint о том, что для этих типов внутренне задан тип ‘any’. При этом я не могу понять, какой тип установить для этих двух, чтобы это не вызывало больше ошибок позже из-за несоответствия типов. К каким типам TypeScript я должен отнести эти два?

Ответ №1:

Встроенный AppProps тип теперь является универсальным. Чтобы использовать свой пользовательский PageProps , просто передайте его в AppProps тип:

 import { AppProps } from 'next/app';

interface CustomPageProps { // <--- your custom page props
   // your props
}

function MyApp({ Component, pageProps }: AppProps<CustomPageProps>) {
                                             //   ^^^ use your custom props here
  return <Component {...pageProps} />
                    // ^^^^^ pageProps is now typeof CustomPageProps
}
  

Комментарии:

1. Это рекомендуемый способ, однако это создает pageProps тип any, который не очень полезен. Есть ли какой-либо способ применить общий при использовании одного из методов выборки даты, например getInitialProps ?

2. @rantao, смотрите мой ответ ниже. Я объясняю AppProps pageProps , как также расширить generic, что дает вам возможность предоставить структуру для начальных реквизитов.

3. @rantao обновил мой ответ — новые встроенные типы из nextjs теперь являются общими.

Ответ №2:

Последнее решение: NextJS AppProps

По состоянию на next.js версия 12.3.0, общий код, переданный в AppProps , будет передан pageProps (см. Соответствующий PR). Смотрите пример ниже:

 // importing the provided NextJS type
import type { AppProps } from "next/app";

// use the type and pass it your page props type
export default function App({
  Component,
  pageProps,
}: AppProps<CustomPageProps>) {
  //...
}
  

Старое решение (предварительно next.js 12.3.0):

Улучшено AppProps , чтобы разрешить настраиваемый pageProps

NextJS предоставляет AppProps тип из коробки, который вы можете импортировать и использовать в своем _app компоненте. Это предоставит запрошенные вами типы. Однако этот тип ограничивается pageProps any типом по умолчанию, который может быть не тем, что вы хотите.

Если вы хотите больше контролировать это, AppProps принимает аргумент типа, но передает его только вниз Component , оставляя pageProps в качестве any типа независимо от того, что.

Мы можем исправить это, изменив AppProps тип, которому фактически передается его аргумент type pageProps . Смотрите рабочий пример ниже.

_app.tsx

 // importing the provided NextJS type
import type { AppProps as NextAppProps } from "next/app";

// modified version - allows for custom pageProps type, falling back to 'any'
type AppProps<P = any> = {
  pageProps: P;
} amp; Omit<NextAppProps<P>, "pageProps">;

// use the new type like so, replacing 'CustomPageProps' with whatever you want
export default function App({
  Component,
  pageProps,
}: AppProps<CustomPageProps>) {
  //...
}
  

Ответ №3:

Если вы все еще получаете предупреждение о «отсутствующем типе возвращаемого значения в функции», просто добавьте возвращаемый тип JSX.Element

 import { AppProps } from 'next/app'

export default function MyApp({ Component, pageProps }: AppProps): JSX.Element {
  return <Component {...pageProps} />
}
  

Ответ №4:

На случай, если вам err тоже нужен объект:

 export default function App({
  Component,
  pageProps,
  err,
}: AppProps amp; { err: any }) {
  // Workaround for https://github.com/vercel/next.js/issues/8592
  return <Component {...pageProps} err={err} />
}
  

Ответ №5:

Я считаю, что вам нужны типы, которые getInitialProps также будут учтены. Вот они:

 type Props<P> = AppProps amp; P;

interface AppType<P> {
  (props: Props<P>): ReactElement;
  getInitialProps?: (context: AppContext) => Props<P> | Promise<Props<P>>;
}
  

Ответ №6:

Документация: https://nextjs.org/docs/basic-features/typescript#custom-app

 import type { AppProps } from 'next/app'

export default function MyApp({ Component, pageProps }: AppProps) {
  return <Component {...pageProps} />
}