メインコンテンツまでスキップ

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 から tsconfig.json ファイルに paths コンパイラオプションをコピーし、jsconfig.json ファイルを削除します。

TypeScriptプラグイン

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

VS Codeでプラグインを有効にするには、次の手順を実行します。

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

TypeScriptのコマンドパレット

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

プラグインの機能

TypeScriptプラグインでは以下のことができます。

  • Segment 構成オプションに無効な値が渡された場合に警告を表示します
  • 利用可能なオプションとコンテキストのドキュメントを表示します
  • use client ディレクティブが正しく使用されていることを確認します
  • Client Component でのみ useState などのクライアントフックが使用されることを保証します

Good to know: 将来的にはさらなる機能が追加される予定です。

最低限のTypeScriptバージョン

インポート名の type 修飾子パフォーマンスの改善 などの文法機能を利用するために、少なくとも TypeScript の v4.5.2 にすることを強くお勧めします。

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

next/linkを使用してページ間を移動する際に、Next.jsではリンクに静的な型付けを行うことができます。これにより、タイポやその他のエラーを防ぐことができ、ページ間の移動時の型の安全性が向上します。

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

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

module.exports = nextConfig

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

現在の実験的なサポートでは、動的Segmentを含む任意の文字列リテラルがサポートされています。リテラル以外の文字列では、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ファイルを生成し、アプリケーションのすべての既存のルートに関する情報を含みます(リンクのhrefタイプとして有効なすべてのルート)。この.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や型安全なクエリビルダを使用することによって実現できます。

Async Server Component の TypeScript エラー

asyncな Server Component を TypeScript で使用するには、TypeScript を5.1.3以上、@types/react18.2.8以上にする必要があります。

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

サーバーとClient Component間でのデータの受け渡し

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

さらに、レンダリングされないデータはサーバーとクライアント間で交換されないため、シリアライズする必要がなくコードも少なくなります。これは、Server Componentのサポートが可能になったことによるものです。

パスのエイリアスとbaseUrl

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

この機能については、モジュールパス エイリアスを参照してください。

next.config.js の型チェック

next.config.jsファイルはJavaScriptファイルなので、BabelやTypeScriptによって解析されることはありませんが、以下のJSDocを使用してIDEで型チェックを行えます。

// @ts-check

/**
* @type {import('next').NextConfig}
**/
const nextConfig = {
/* config options here */
}

module.exports = nextConfig

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

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

TypeScriptエラーを無視する方法

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

アプリケーションにエラーがある場合でも、Next.jsに修正を無視させて本番コードを生成する場合は、ビルドインの型チェックのステップを無効にできます。

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

next.config.jsを開き、typescript構成のignoreBuildErrorsオプションを有効にします。

next.config.js
module.exports = {
typescript: {
// !! WARN !!
// プロジェクトに型エラーがある場合でも、本番ビルドを正常に完了させるようにします。
// !! WARN !!
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.0より高速なビルドのために、TypeScriptとTSXのコンパイルはデフォルトで SWC が使用されるようになりました。
v10.2.1インクリメンタルな型チェックがサポートされ、tsconfig.jsonで有効になりました。