TypeScript

Next.js は React アプリケーション構築のための TypeScript ファーストな開発体験を提供します。

必要なパッケージの自動インストールと適切な設定の構成を備えた、組み込みの TypeScript サポートが含まれています。

さらに、エディター向けの TypeScript プラグイン も提供しています。

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

新しいプロジェクト

create-next-app は現在、デフォルトで TypeScript を同梱しています。

Terminal
npx create-next-app@latest

既存のプロジェクト

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

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

TypeScript プラグイン

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

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

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

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

プラグイン機能

TypeScript プラグインは以下に役立ちます:

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

豆知識: 今後さらに機能が追加される予定です。

TypeScript の最低バージョン

import 名の型修飾子パフォーマンス改善 などの構文機能を得るためには、少なくとも TypeScript v4.5.2 以上を使用することを強く推奨します。

静的に型付けされたリンク

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

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

next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    typedRoutes: true,
  },
}

module.exports = nextConfig

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

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

import type { Route } from 'next';
import Link from 'next/link'

// href が有効なルートの場合、TypeScript エラーは発生しない
<Link href="/about" />
<Link href="/blog/nextjs" />
<Link href={`/blog/${slug}`} />
<Link href={('/blog' + slug) as Route} />

// href が有効なルートでない場合、TypeScript エラーが発生
<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 は .next 内に隠れた .d.ts ファイルを生成します。このファイルにはアプリケーション内のすべての既存ルート情報(Linkhref 型として有効なすべてのルート)が含まれます。この .d.ts ファイルは tsconfig.json に含まれ、TypeScript コンパイラはこの .d.ts をチェックし、エディターで無効なリンクについてフィードバックを提供します。

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

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/...')
  // 戻り値はシリアライズされません
  // Date、Map、Set などを返せます
  return res.json()
}

export default async function Page() {
  const name = await getData()

  return '...'
}

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

非同期 Server Component の TypeScript エラー

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 の最新バージョンに更新すればこの問題は解決します。

サーバーとクライアントコンポーネント間のデータ受け渡し

Server Component と Client Component 間で props を通じてデータを渡す場合、ブラウザで使用するためにデータは依然としてシリアライズ(文字列変換)されます。ただし、特別な型は必要ありません。コンポーネント間で他の props を渡すのと同じように型付けされます。

さらに、レンダリングされないデータはサーバーとクライアント間を移動しない(サーバー上に残る)ため、シリアライズされるコードは少なくなります。これは Server Components のサポートによって初めて可能になりました。

パスエイリアスと baseUrl

Next.js は tsconfig.json"paths""baseUrl" オプションを自動的にサポートします。

この機能について詳しくは モジュールパスエイリアスドキュメント をご覧ください。

next.config.js の型チェック

next.config.js ファイルは Babel や TypeScript で解析されないため JavaScript ファイルである必要がありますが、JSDoc を使用して IDE で型チェックを追加できます:

// @ts-check

/**
 * @type {import('next').NextConfig}
 **/
const nextConfig = {
  /* ここに設定オプション */
}

module.exports = nextConfig

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

v10.2.1 以降、Next.js は tsconfig.json で有効にした場合の インクリメンタル型チェック をサポートしています。これは大規模アプリケーションでの型チェック速度向上に役立ちます。

TypeScript エラーの無視

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

アプリケーションにエラーがある場合でも Next.js に危険を承知でプロダクションコードを生成させたい場合は、組み込みの型チェックステップを無効にできます。

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

next.config.js を開き、typescript 設定で ignoreBuildErrors オプションを有効にします:

next.config.js
module.exports = {
  typescript: {
    // !! 警告 !!
    // プロジェクトに型エラーがあってもプロダクションビルドを成功させる
    // !! 警告 !!
    ignoreBuildErrors: true,
  },
}

カスタム型宣言

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

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

バージョン変更点

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