NextJS _app.tsx Component 和 pageProps 应该是啥 TypeScript 类型?

Posted

技术标签:

【中文标题】NextJS _app.tsx Component 和 pageProps 应该是啥 TypeScript 类型?【英文标题】:What TypeScript type should NextJS _app.tsx Component and pageProps be?NextJS _app.tsx Component 和 pageProps 应该是什么 TypeScript 类型? 【发布时间】:2021-02-19 16:05:49 【问题描述】:

这是来自 NextJS 的默认 _app.tsx:

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

问题是,一旦您切换到 TypeScript,您就会在 ES6Lint 下收到警告,指出这些类型本质上设置为类型“任何”。话虽如此,我无法弄清楚将这两个设置为哪种类型,以后不会导致更多错误类型不匹配。我应该将这两个转换为什么 TypeScript 类型?

【问题讨论】:

【参考方案1】:

您可以从nextjs 导入类型。

import  AppProps  from 'next/app';

function MyApp( Component, pageProps : AppProps) 
  return <Component ...pageProps />

【讨论】:

这是推荐的方式,但是这使得pageProps 成为any 类型,这不是很有用。使用其中一种日期获取方法(例如getInitialProps)时,有什么方法可以应用泛型? @rantao,请参阅下面的答案。我解释了如何使 AppProps 泛型也扩展到 pageProps,这使您可以选择为初始道具提供结构。【参考方案2】:

改进了AppProps 以允许自定义pageProps

NextJS 提供了一个开箱即用的AppProps 类型,您可以轻松地在_app 组件中导入和使用它。这将提供您要求的类型。但是,正如另一条评论中提到的,这种类型默认将pageProps 限制为 any 类型,这可能不是您想要的。

如果您想对此进行更多控制,事实证明AppProps 确实接受了一个类型参数,但只将其传递给Component,留下pageProps 作为any随便输入。

我们可以通过调整AppProps 类型来解决这个问题,该类型实际上也将它的类型参数传递给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;
 & 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 &  err: any ) 
  // Workaround for https://github.com/vercel/next.js/issues/8592
  return <Component ...pageProps err=err />

【讨论】:

【参考方案5】:

我相信您也需要getInitialProps 能够赶上的类型。 他们在那里:

type Props<P> = AppProps & P;

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

【讨论】:

以上是关于NextJS _app.tsx Component 和 pageProps 应该是啥 TypeScript 类型?的主要内容,如果未能解决你的问题,请参考以下文章

反应与 Nextjs 的光滑兼容性

Nextjs - 如果在客户端运行,则注入 ContextProvider

React - nextjs 在 useEffect 中调用自定义钩子

NextJS/Typescript/Apollo 错误;类型上不存在属性

Next.js 不会在 _app.tsx 中传递用户属性

如何将 Redux devtools 与 Nextjs 一起使用?