Menu

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ファイルを削除してください。

さらに、型推論を改善するために、next.config.jsの代わりにnext.config.tsの使用をお勧めします。

TypeScriptプラグイン

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

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バージョン

型修飾子付きインポート名パフォーマンス改善などの構文機能を利用するために、TypeScriptのv4.5.2以上を強くお勧めします。

Next.js設定での型チェック

next.config.jsの型チェック

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

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

next.config.tsの型チェック

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

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

注意: next.config.tsでのモジュール解決は現在、CommonJSに限定されています。これにより、next.config.tsにロードされるESMのみのパッケージとの間に非互換性が生じる可能性があります。

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

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'
 
// 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できます。このデータをクライアント側で消費するためにシリアライズ(文字列に変換)する必要はありません。代わりに、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や型安全なクエリビルダーを使用することで可能になります。

非同期サーバーコンポーネントのTypeScriptエラー

asyncサーバーコンポーネントをTypeScriptで使用するには、TypeScript 5.1.3以降と@types/react 18.2.8以降を使用していることを確認してください。

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

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

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

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

パスエイリアスと baseUrl

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

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

増分型チェック

v10.2.1 以降、Next.jsは tsconfig.json で有効にされた場合、増分型チェックをサポートします。これは大規模なアプリケーションでの型チェックを高速化するのに役立ちます。

TypeScriptエラーの無視

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

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

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

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

next.config.ts
import type { NextConfig } from 'next'
 
const nextConfig: NextConfig = {
  typescript: {
    // !! 警告 !!
    // プロジェクトに型エラーがある場合でも、
    // 本番ビルドを成功させることを危険に許可します。
    // !! 警告 !!
    ignoreBuildErrors: true,
  },
}
 
export default nextConfig

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

カスタム型宣言

カスタム型を宣言する必要がある場合、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"]
}

バージョンの変更

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