带有 NextJS 的打字稿

Posted

技术标签:

【中文标题】带有 NextJS 的打字稿【英文标题】:Typescript with NextJS 【发布时间】:2019-10-15 06:19:24 【问题描述】:

我一直在努力将 Typescript 与 NextJS 集成,主要是与 getInitialProps 中的解构参数以及页面函数的类型。例如,这是我的 _app.tsx:

import  ThemeProvider  from 'styled-components';
import App,  Container  from 'next/app';
import Cookie from 'js-cookie';
import React from 'react';

import  CookiesProvider  from '../components/CookiesContext';
import THEME from '../styles/config';

import 
  GlobalStyles,
  Wrapper,
 from './_app.style';

type Props = 
  cookieSettings: 
    functionalOn: string;
    performanceOn: string;
  
;

class Page extends App<Props> 
  static async getInitialProps(
    Component,
    ctx,
  ) 
    // Get initial page props
    const pageProps = Component.getInitialProps ? await Component.getInitialProps(ctx) : ;

    // Get cookies settings
    const cookieSettings = 
      functionalOn: process.browser ? Cookie.get('functionalCookies') : ctx.req.cookies.functionalCookies,
      performanceOn: process.browser ? Cookie.get('performanceCookies') : ctx.req.cookies.performanceCookies,
    ;

    return 
      cookieSettings,
      pageProps,
    ;
  

  render() 
    const 
      Component,
      cookieSettings,
      pageProps,
     = this.props;

    return (
      <Container>
        <ThemeProvider theme=THEME>
          <CookiesProvider ...cookieSettings>
            <Wrapper>
              <GlobalStyles />
              <Component ...pageProps />
            </Wrapper>
          </CookiesProvider>
        </ThemeProvider>
      </Container>
    );
  


export default Page;

我在这里得到的唯一错误是 Component 和 ctx 参数隐含地属于“任何”类型。我正在使用@types/next,以及包含类型的 NextJS 的 v8.1.1.Canary.40,所以我认为这样的东西会被涵盖,但我似乎必须自己声明它们是什么,而我没有知道,因为它是第三方包。

另外,我有一个这样的页面文件:

import  NextPage  from 'next';
import React,  Fragment  from 'react';

import Metadata from '../components/Metadata';
import withPageError from '../components/PageError/withPageError';

type Props = 
  // TODO: Add props
;

const getInitialProps = async ( res ) => 
  const page = await getPageData();
  if (!page && res) res.statusCode = 404;
  if (!page) return ;
  return  page ;
;

const Page: NextPage<Props> = () => (
  <Fragment>
    <Metadata
      pageDescription="Page"
      pageTitle="Page"
      socialDescription="Page"
      socialTitle="Page"
    />
  </Fragment>
);

Page.getInitialProps = getInitialProps;

export default withPageError(Page);

在这里,我在 Page.getInitialProps 上看到红色波浪线,并出现以下错误:

Type '( res : res: any; ) =&gt; Promise&lt; page?: undefined; | page: any; &gt;' is not assignable to type '(ctx: NextPageContext) =&gt; Promise&lt;Props&gt;'.

const Page 上的错误也很大,对我来说没有任何意义。

我在这一切中缺少什么?当然,我不必为大量 NextJS 东西重新声明类型?

【问题讨论】:

【参考方案1】:

你只需要像这样输入 getInitialProps:

import React from 'react'
import  NextPageContext  from 'next'

interface Props 
  userAgent?: string;


export default class Page extends React.Component<Props> 
  static async getInitialProps( req : NextPageContext) 
    const userAgent = req ? req.headers['user-agent'] : navigator.userAgent
    return  userAgent 
  

  render() 
    const  userAgent  = this.props
    return <main>Your user agent: userAgent</main>
  

Next.js 文档 - https://nextjs.org/docs/api-reference/data-fetching/getInitialProps

【讨论】:

【参考方案2】:

getInitialProps 应该返回一个 Props 类型的对象。但它返回 page 并且属性pagePage 类型中不存在。

【讨论】:

【参考方案3】:

拉入 AppProps 以访问应用程序的属性。

import  AppProps  from 'next/app'
 

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

【讨论】:

以上是关于带有 NextJS 的打字稿的主要内容,如果未能解决你的问题,请参考以下文章

如何使 Next.js getStaticProps 与打字稿一起使用

带有打字稿的枚举

带有打字稿的 Angular 5 websocket 示例

带有 Vue js 的打字稿

如何解决全局 node.js 对象上的这个打字稿错误

带有打字稿的MongoDB聚合