まくろぐ

Next.js のプロジェクトを TypeScript 化する

更新:
作成:

何をするか?

Next.js は TypeScript による開発を強力にサポートしており、簡単に環境導入することができます。 ここでは、create-next-app で作成した Next.js プロジェクトに対して、TypeScript の開発環境を追加します。

もし、まだ Next.js のプロジェクトを作成していなければ、次のように新規作成してください。

$ npx create-next-app myapp

TypeScript 環境の導入

Next.js は、プロジェクトのルートに tsconfig.json ファイルがあると、自動的に TypeScript モードで動作するようになります。 次のようにして、空の tsconfig.json ファイルを作成し、TypeScript 用のパッケージをインストールします。

$ touch tsconfig.json
$ npm install typescript @types/node @types/react --save-dev

なんと、これだけで Next.js プロジェクトへの TypeScript 導入は完了です。 お手軽〜

自動生成される設定ファイルを見ておく

上記のステップで、TypeScript の設定ファイル (tsconfig.json) に何も記述していないことに気づいたかもしれません。 実は、Next.js のビルド(next devnext build)を実行すると、自動的に設定ファイルの内容を更新してくれるようになっています。

Next.js 開発サーバーの起動 (next dev)
$ npm run dev

例えば上記のように開発サーバーを起動すると、空っぽだった tsconfig.json が次のような内容に初期化されます。 まさにゼロコンフィグです。

{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": false,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve"
  },
  "include": [
    "next-env.d.ts",
    "**/*.ts",
    "**/*.tsx"
  ],
  "exclude": [
    "node_modules"
  ]
}

さらに、Next.js はプロジェクトのルートに next-env.d.ts というファイルを生成します。 このファイルには、Next.js が提供するコンポーネントなどの型情報が含まれています。

next-env.d.ts
/// <reference types="next" />
/// <reference types="next/types/global" />

デフォルトでは上記のような内容になっていて、node_modules/next 下にインストールされた型情報ファイルを参照するようになっています。 このファイルは Next.js が勝手に更新するので、マニュアルで更新する必要はありません。

既存の JavaScript コードを TypeScript コードに置き換える

拡張子を .js から .tsx に置換する

TypeScript 環境の導入をサクッと完了したら、既存の JavaScript ファイル (.js) を TypeScript ファイル(.ts および .tsx)に置き換えていきます。 JavaScript ファイルは pages ディレクトリ以下に格納されているので、まずは、それらのファイルの拡張子を変更します。

pages/
  +-- _app.js  (→ _app.tsx)
  +-- api/
  |     +-- hello.js  (→ hello.ts)
  +-- index.js  (→ index.tsx)

api ディレクトリの中の .js ファイルには JSX が含まれていないので、それだけは .ts にして、他のファイルは .tsx にしてしまえばよいでしょう。

厳格な型チェック(strict モード)を ON にする

ファイルの拡張子を .ts.tsx にしたので、ビルド時に TypeScript の型チェックが働くようになるはずが、npm run devnpm run build してもビルドエラーにはなりません。 なぜなら、tsconfig.jsonstrict 設定が false になっており、暗黙的な any 型の使用が許されているからです。 次のように tsconfig.json を修正して、型チェックを強制するようにしましょう。 ついでに、allowJs はもう必要ないので false にしておきます。

tsconfig.json(修正箇所抜粋)
{
  ...
  "allowJs": false,  // ← js ファイルは扱わない
  "skipLibCheck": true,
  "strict": true,  // ← 型チェックなどを厳密に行う
  ...
}

これで、ビルド時にちゃんと型情報に関するエラーを出してくれるようになります。

$ npm run build
...
Failed to compile.

./pages/_app.tsx:3:18
Type error: Binding element 'Component' implicitly has an 'any' type.
...

TypeScript コードの修正

ビルドエラーにならないように、TypeScript コードに型情報を追加していきます。

pages/_app.tsx
import type { AppProps } from 'next/app'

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

export default MyApp
pages/api/hello.ts
import type { NextApiRequest, NextApiResponse } from 'next'

export default (req: NextApiRequest, res: NextApiResponse) => {
  res.status(200).json({ name: 'John Doe' })
}

これで、正しくビルドが通るようになります。 Next.js が提供する他の型情報に関しては、下記のサイトを参考にしてください。

おまけ(example 機能で TypeScript 導入済みのプロジェクトを作成する)

create-next-app コマンドで Next.js プロジェクトを作成するときに、--example オプションを使用すると、GitHub 上の任意のテンプレートを使ってプロジェクトを作成できます。 Next.js (Vercel) 公式のテンプレートが、下記のリポジトリにたくさん用意されています。

例えば、TypeScript 導入済みのテンプレートである with-typescript を使って Next.js プロジェクトを作成したいときは、次のように create-next-app コマンドを実行します。

$ npx create-next-app --example with-typescript myapp

こうすれば、最初から TypeScript 環境が導入された状態でプロジェクトが作成されるので、ここまで説明してきたような手作業での TypeScript 導入をしなくて済みます。 とはいえ、手作業で導入しても大した手間ではないので、好きな方を選べばよいと思います。

関連記事

まくろぐ
サイトマップまくへのメッセージ