コンテンツにスキップ

TypeScript

Next.jsにはTypeScriptが組み込まれており、create-next-appで新しいプロジェクトを作成すると、必要なパッケージが自動的にインストールされ、適切な設定が行われます。

既存のプロジェクトにTypeScriptを追加するには、ファイルの名前を.tsまたは.tsxに変更します。next devnext buildを実行すると、必要な依存関係が自動的にインストールされ、推奨される設定オプションを含むtsconfig.jsonファイルが追加されます。

ヒント: 既存のjsconfig.jsonファイルがある場合は、古いjsconfig.jsonからpathsコンパイラオプションを新しいtsconfig.jsonファイルにコピーし、古いjsconfig.jsonファイルを削除してください。

IDEプラグイン

Next.jsにはカスタムTypeScriptプラグインと型チェッカーが含まれており、VSCodeやその他のコードエディタで高度な型チェックと自動補完に利用できます。

VS Codeでプラグインを有効にするには

  1. コマンドパレットを開き (Ctrl/⌘ + Shift + P)
  2. 「TypeScript: Select TypeScript Version」を検索
  3. 「Use Workspace Version」を選択
TypeScript Command Palette

これで、ファイルを編集する際にカスタムプラグインが有効になります。next buildを実行すると、カスタム型チェッカーが使用されます。

TypeScriptプラグインは以下の点で役立ちます。

  • セグメント設定オプションに無効な値が渡された場合に警告を表示する。
  • 利用可能なオプションとコンテキストに応じたドキュメントを表示する。
  • use clientディレクティブが正しく使用されていることを確認する。
  • クライアントフック(useStateなど)がClient Componentsでのみ使用されていることを確認する。

🎥 動画: 組み込みのTypeScriptプラグインについて学ぶ → YouTube (3分)

エンドツーエンドの型安全性

Next.js App Routerは型安全性が強化されています。これには以下が含まれます。

  1. フェッチ関数とページ間でのデータシリアライゼーション不要: コンポーネント、レイアウト、およびサーバー上のページで直接fetchを実行できます。このデータをReactで利用するためにクライアント側に渡すためにシリアライズ(文字列に変換)する必要はありません。代わりに、appはデフォルトでServer Componentsを使用するため、DateMapSetなどの値を追加の手順なしで使用できます。以前は、Next.js固有の型を使用してサーバーとクライアントの境界を手動で型付けする必要がありました。
  2. コンポーネント間の合理化されたデータフロー: ルートレイアウトを優先して_appが削除されたことにより、コンポーネントとページ間のデータフローを視覚化しやすくなりました。以前は、個々のpages_app間を流れるデータは型付けが難しく、混乱を招くバグを引き起こす可能性がありました。App Routerの共存データフェッチにより、これはもはや問題ではありません。

Next.jsでのデータフェッチは、データベースやコンテンツプロバイダーの選択を規定することなく、可能な限りエンドツーエンドの型安全性を提供します。

通常のTypeScriptと同様に、レスポンスデータを型付けすることができます。例えば、

app/page.tsx
async function getData() {
  const res = await fetch('https://api.example.com/...')
  // The return value is *not* serialized
  // You can return Date, Map, Set, etc.
  return res.json()
}
 
export default async function Page() {
  const name = await getData()
 
  return '...'
}

完全なエンドツーエンドの型安全性を実現するには、データベースまたはコンテンツプロバイダーがTypeScriptをサポートしている必要もあります。これは、ORMまたは型安全なクエリビルダーを使用することで実現できます。

next.config.tsの型チェック

next.config.tsを使用することで、Next.jsの設定ファイルでTypeScriptを使い、型をインポートできます。

next.config.ts
import type { NextConfig } from 'next'
 
const nextConfig: NextConfig = {
  /* config options here */
}
 
export default nextConfig

ヒント: next.config.tsでのモジュール解決は現在CommonJSに制限されています。これにより、ESMのみのパッケージがnext.config.tsで読み込まれる場合に互換性の問題が発生する可能性があります。

next.config.jsファイルを使用する場合、以下のようにJSDocを使ってIDEで型チェックを追加できます。

next.config.js
// @ts-check
 
/** @type {import('next').NextConfig} */
const nextConfig = {
  /* config options here */
}
 
module.exports = nextConfig

Next.jsは、next/linkを使用する際にタイプミスやその他のエラーを防ぐためにリンクを静的に型付けでき、ページ間のナビゲーションにおける型安全性を向上させます。

この機能を有効にするには、experimental.typedRoutesを有効にし、プロジェクトでTypeScriptを使用する必要があります。

next.config.ts
import type { NextConfig } from 'next'
 
const nextConfig: NextConfig = {
  experimental: {
    typedRoutes: true,
  },
}
 
export default nextConfig

Next.jsは、アプリケーション内の既存のすべてのルートに関する情報を含むリンク定義を.next/typesに生成し、TypeScriptはそれを使用してエディタで無効なリンクに関するフィードバックを提供できます。

現在、実験的なサポートには、動的セグメントを含む任意の文字列リテラルが含まれます。非リテラル文字列の場合、現時点ではhrefas Routeで手動でキャストする必要があります。

import type { Route } from 'next';
import Link from 'next/link'
 
// No TypeScript errors if href is a valid route
<Link href="/about" />
<Link href="/blog/nextjs" />
<Link href={`/blog/${slug}`} />
<Link href={('/blog' + slug) as Route} />
 
// TypeScript errors if href is not a valid route
<Link href="/aboot" />

next/linkをラップするカスタムコンポーネントでhrefを受け入れるには、ジェネリックを使用します。

import type { Route } from 'next'
import Link from 'next/link'
 
function Card<T extends string>({ href }: { href: Route<T> | URL }) {
  return (
    <Link href={href}>
      <div>My Card</div>
    </Link>
  )
}

仕組み

next devまたはnext buildを実行すると、Next.jsはアプリケーション内の既存のすべてのルート(Linkhref型としてすべての有効なルート)に関する情報を含む隠し.d.tsファイルを.next内に生成します。この.d.tsファイルはtsconfig.jsonに含まれており、TypeScriptコンパイラは.d.tsをチェックし、エディタで無効なリンクに関するフィードバックを提供します。

非同期サーバーコンポーネントを使用する場合

TypeScriptでasync Server Componentを使用するには、TypeScript 5.1.3以上および@types/react 18.2.8以上を使用していることを確認してください。

古いバージョンのTypeScriptを使用している場合、'Promise<Element>' is not a valid JSX elementという型エラーが表示されることがあります。TypeScriptおよび@types/reactを最新バージョンに更新すると、この問題が解決されます。

インクリメンタル型チェック

v10.2.1以降、Next.jsはtsconfig.jsonで有効にした場合にインクリメンタル型チェックをサポートしており、これにより大規模なアプリケーションでの型チェックを高速化できます。

本番環境でのTypeScriptエラーの無効化

プロジェクトにTypeScriptエラーが存在する場合、Next.jsは本番ビルドnext build)を失敗させます。

アプリケーションにエラーがある場合でもNext.jsが危険な本番コードを生成するようにしたい場合は、組み込みの型チェックステップを無効にすることができます。

無効にする場合は、ビルドまたはデプロイプロセスの一部として型チェックを実行していることを確認してください。そうしないと、非常に危険な場合があります。

next.config.tsを開き、typescript設定のignoreBuildErrorsオプションを有効にします。

next.config.ts
import type { NextConfig } from 'next'
 
const nextConfig: NextConfig = {
  typescript: {
    // !! WARN !!
    // Dangerously allow production builds to successfully complete even if
    // your project has type errors.
    // !! WARN !!
    ignoreBuildErrors: true,
  },
}
 
export default nextConfig

ヒント: ビルド前にTypeScriptエラーを自分でチェックするために、tsc --noEmitを実行できます。これは、デプロイ前にTypeScriptエラーをチェックしたいCI/CDパイプラインで役立ちます。

カスタム型宣言

カスタム型を宣言する必要がある場合、next-env.d.tsを修正したくなるかもしれません。しかし、このファイルは自動生成されるため、変更は上書きされます。代わりに、new-types.d.tsという新しいファイルを作成し、tsconfig.jsonで参照するようにしてください。

tsconfig.json
{
  "compilerOptions": {
    "skipLibCheck": true
    //...truncated...
  },
  "include": [
    "new-types.d.ts",
    "next-env.d.ts",
    ".next/types/**/*.ts",
    "**/*.ts",
    "**/*.tsx"
  ],
  "exclude": ["node_modules"]
}

バージョン変更履歴

バージョン変更点
v15.0.0TypeScriptプロジェクトでnext.config.tsのサポートが追加されました。
v13.2.0静的に型付けされたリンクがベータ版で利用可能になりました。
v12.0.0SWCがTypeScriptおよびTSXのコンパイルにデフォルトで使用されるようになり、ビルドが高速化されました。
v10.2.1tsconfig.jsonで有効にした場合にインクリメンタル型チェックのサポートが追加されました。