使用TypeScript在Next.js中使用getInitialProps

luk*_*kas 14 typescript definitelytyped nextjs

从文档,Next.js 5.0公告和互联网上的各种文章看来,Next.js很好地支持TypeScript,很多人都在使用它.

但是这些线程表明getInitialProps,这对Next.js应用程序至关重要,不起作用:

我该如何解决?在类和功能组件中,当我这样做时,ComponentName.getInitialProps = async function() {...}我收到以下错误:

[ts] Property 'getInitialProps' does not exist on type '({ data }: { data: any; }) => Element'.
Run Code Online (Sandbox Code Playgroud)

Mik*_*zic 23

解决问题的经典方法是声明getInitialProps为静态成员:

class MyComponent extends React.Component<{...}, {}> {

  static async getInitialProps(ctx: any) {
    return {...}
  }

  render() {...}

}
Run Code Online (Sandbox Code Playgroud)

使用无状态组件时,您可以声明一个简单的扩展React.SFC:

interface StatelessPage<P = {}> extends React.SFC<P> {
  getInitialProps?: (ctx: any) => Promise<P>
}

const MyComponent: StatelessPage<{...}> = (...) => ...

MyComponent.getInitialProps = async (ctx) => {...}
Run Code Online (Sandbox Code Playgroud)


Jam*_*and 19

自从Next.js现在正式支持TypeScript以来,以上答案已经过时了(此处的公告)

此发行版的一部分是更好的TypeScript类型,其中许多Next.js是用TypeScript本身编写的。这意味着@types/next将不赞成使用该软件包,而应使用官方的Next.js类型。

相反,您应该导入NextPage类型并将其分配给组件。您也可以getInitialProps使用类型进行NextPageContext键入。

import { NextPage, NextPageContext } from 'next';

const MyComponent: NextPage<MyPropsInterface> = props => (
  // ...
)

interface Context extends NextPageContext {
  // any modifications to the default context, e.g. query types
}

MyComponent.getInitialProps = async (ctx: Context) => {
  // ...
  return props
}

Run Code Online (Sandbox Code Playgroud)

  • @Alp非页面组件不能使用`getInitialProps`。因此,您只需像正常的react组件一样键入它(一些道具接口,推断返回类型是我的最爱。您也可以使用`React.FunctionComponent`) (2认同)

Jus*_*oel 9

Next.js的类型在DefinitelyTyped项目中维护,该项目具有新版本7.0.6。

为了使用新类型,请确保将它们导入项目中:

npm install --save-dev @types/next@7.0.6
Run Code Online (Sandbox Code Playgroud)

这是您键入getInitialProps无状态功能组件的方式:

import { NextFunctionComponent, NextContext } from 'next'

// Define what an individual item looks like
interface IDataObject {
  id: number,
  name: string
}

// Define the props that getInitialProps will inject into the component
interface IListComponentProps {
  items: IDataObject[]
}

const List: NextFunctionComponent<IListComponentProps> = ({ items }) => (
  <ul>
    {items.map((item) => (
      <li key={item.id}>
        {item.id} -- {item.name}
      </li>
    ))}
  </ul>
)

List.getInitialProps = async ({ pathname }: NextContext) => {
  const dataArray: IDataObject[] =
    [{ id: 101, name: 'larry' }, { id: 102, name: 'sam' }, { id: 103, name: 'jill' }, { id: 104, name: pathname }]

  return { items: dataArray }
}

export default List
Run Code Online (Sandbox Code Playgroud)

这是您输入getInitialProps课程的方式:

import React from 'react'
import { NextContext } from 'next'

// Define what an individual item looks like
interface IDataObject {
  id: number,
  name: string
}

// Define the props that getInitialProps will inject into the component
interface IListClassProps {
  items: IDataObject[]
}

class List extends React.Component<IListClassProps> {
  static async getInitialProps({ pathname }: NextContext) {
    const dataArray: IDataObject[] =
      [{ id: 101, name: 'larry' }, { id: 102, name: 'sam' }, { id: 103, name: 'jill' }, { id: 104, name: pathname }]

    return { items: dataArray }
  }

  render() {
    return (
      <ul>
        {this.props.items.map((item) => (
          <li key={item.id}>
            {item.id} -- {item.name}
          </li>
        ))}
      </ul>
    )
  }
}

export default List
Run Code Online (Sandbox Code Playgroud)

如果您查看DefinitelyTyped中测试,则可以获取有关如何在Next中使用其他类型的输入的大量见解。