ドキュメント、Next.js 5.0の発表、およびインターネットに関するさまざまな記事から、Next.jsはTypeScriptを十分にサポートしており、多くの人が使用しているようです。
しかし、これらのスレッドは、Next.jsアプリに不可欠なgetInitialProps
が機能しないことを示唆しています。
どうすれば修正できますか?クラスコンポーネントと機能コンポーネントの両方で、ComponentName.getInitialProps = async function() {...}
を実行すると、次のエラーが表示されます。
[ts] Property 'getInitialProps' does not exist on type '({ data }: { data: any; }) => Element'.
編集:この回答は、Next 9のリリース以来古くなっています。以下の回答を参照してください。
問題を解決する古典的な方法は、getInitialProps
を静的メンバーとして宣言することです。
class MyComponent extends React.Component<{...}, {}> {
static async getInitialProps(ctx: any) {
return {...}
}
render() {...}
}
ステートレスコンポーネントを使用する場合、React.SFC
の単純な拡張を宣言できます。
interface StatelessPage<P = {}> extends React.SFC<P> {
getInitialProps?: (ctx: any) => Promise<P>
}
const MyComponent: StatelessPage<{...}> = (...) => ...
MyComponent.getInitialProps = async (ctx) => {...}
Next.jsがTypeScriptを公式にサポートするようになったため、上記の回答は古くなっています(お知らせ here )
このリリースの一部はより優れたTypeScript型であり、Next.jsの多くはTypeScript自体で記述されています。これは、@types/next
パッケージは、公式のNext.jsタイピングを支持して廃止されます。
代わりに、 NextPage
type をインポートして、コンポーネントに割り当てる必要があります。 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
}
Next.jsのタイプは、新しいバージョン7.0.6を持つ DefinitelyTypedプロジェクト で維持されます。
新しいタイプを使用するには、プロジェクトにインポートしていることを確認してください。
npm install --save-dev @types/[email protected]
ステートレス機能コンポーネントに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
クラスの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
DefinitelyTypedのテスト を確認すると、Nextの入力の他のバリエーションの使用方法に関する多くの洞察を得ることができます。