TypeScript
Next.jsには組み込みのTypeScriptサポートがあり、create-next-app
で新しいプロジェクトを作成すると、必要なパッケージが自動的にインストールされ、適切な設定が行われます。
既存のプロジェクトにTypeScriptを追加するには、ファイルの拡張子を.ts
/.tsx
に変更します。next dev
とnext build
を実行すると、必要な依存関係が自動的にインストールされ、推奨設定を含むtsconfig.json
ファイルが追加されます。
補足: すでに
jsconfig.json
ファイルがある場合は、古いjsconfig.json
からpaths
コンパイラオプションを新しいtsconfig.json
ファイルにコピーし、古いjsconfig.json
ファイルを削除してください。
IDE プラグイン
Next.jsにはカスタムTypeScriptプラグインと型チェッカーが含まれており、VSCodeやその他のコードエディタで高度な型チェックと自動補完を利用できます。
VS Codeでプラグインを有効にするには:
- コマンドパレットを開き(
Ctrl/⌘
+Shift
+P
) - 「TypeScript: Select TypeScript Version」を検索
- 「Use Workspace Version」を選択
これでファイルを編集する際にカスタムプラグインが有効になります。next build
を実行すると、カスタム型チェッカーが使用されます。
TypeScriptプラグインは以下のような支援を提供します:
- セグメント設定オプションに無効な値が渡された場合の警告
- 利用可能なオプションとコンテキスト内ドキュメントの表示
use client
ディレクティブが正しく使用されていることの確認- クライアントフック(
useState
など)がクライアントコンポーネントでのみ使用されていることの確認
🎥 動画: 組み込みTypeScriptプラグインについて学ぶ → YouTube(3分間)
エンドツーエンドの型安全性
Next.jsのAppルーターは強化された型安全性を備えています。これには以下が含まれます:
- データ取得関数とページの間でのシリアライズが不要: サーバー上のコンポーネント、レイアウト、ページで直接
fetch
できます。このデータはクライアント側でReactで消費するために、シリアライズ(文字列に変換)する必要はありません。代わりに、app
はデフォルトでサーバーコンポーネントを使用するため、追加手順なしでDate
、Map
、Set
などの値を使用できます。以前は、Next.js固有の型を使用してサーバーとクライアントの境界を手動で型付けする必要がありました。 - コンポーネント間のデータフローの合理化: ルートレイアウトを採用して
_app
が不要になったことで、コンポーネントとページ間のデータフローを視覚化しやすくなりました。以前は、個々のpages
と_app
の間を流れるデータの型付けが難しく、混乱を招くバグが発生する可能性がありました。Appルーターの共存データフェッチングにより、この問題は解消されました。
Next.jsでのデータフェッチングは、データベースやコンテンツプロバイダの選択について制限することなく、可能な限りのエンドツーエンド型安全性を提供します。
通常のTypeScriptと同様に、レスポンスデータの型付けが可能です。例えば:
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や型安全なクエリビルダーを使用することで実現できます。
例
next.config.ts
の型チェック
next.config.ts
を使用して、Next.js設定でTypeScriptを使い、型をインポートすることができます。
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
/* ここに設定オプション */
}
export default nextConfig
補足:
next.config.ts
でのモジュール解決は現在CommonJS
に限定されています。これにより、next.config.ts
で読み込まれるESMのみのパッケージとの非互換性が発生する可能性があります。
next.config.js
ファイルを使用する場合、以下のようにJSDocを使用してIDEで型チェックを追加できます:
// @ts-check
/** @type {import('next').NextConfig} */
const nextConfig = {
/* ここに設定オプション */
}
module.exports = nextConfig
静的に型付けされたリンク
Next.jsはnext/link
を使用する際のタイプミスやその他のエラーを防ぐために、リンクを静的に型付けすることができ、ページ間のナビゲーション時の型安全性を向上させます。
この機能を利用するには、experimental.typedRoutes
を有効にし、プロジェクトでTypeScriptを使用している必要があります。
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
experimental: {
typedRoutes: true,
},
}
export default nextConfig
Next.jsは.next/types
にリンク定義を生成し、アプリケーション内の既存のすべてのルートに関する情報を含めます。TypeScriptはこれを使用して、無効なリンクに関するフィードバックをエディタで提供できます。
現在、実験的なサポートには動的セグメントを含むすべての文字列リテラルが含まれています。リテラルでない文字列については、現在href
をas 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はアプリケーション内の既存のすべてのルート(Link
のhref
型として有効なすべてのルート)に関する情報を含む隠れた.d.ts
ファイルを.next
内に生成します。この.d.ts
ファイルはtsconfig.json
に含まれており、TypeScriptコンパイラはその.d.ts
をチェックして、無効なリンクに関するフィードバックをエディタで提供します。
非同期サーバーコンポーネントでの使用
TypeScriptでasync
サーバーコンポーネントを使用するには、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
オプションを有効にします:
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
typescript: {
// !! 警告 !!
// プロジェクトに型エラーがあっても本番ビルドが
// 成功するように危険に許可します。
// !! 警告 !!
ignoreBuildErrors: true,
},
}
export default nextConfig
補足: ビルド前にTypeScriptエラーをチェックするには、
tsc --noEmit
を実行できます。これはデプロイ前にTypeScriptエラーをチェックしたいCI/CDパイプラインで便利です。
カスタム型宣言
カスタム型を宣言する必要がある場合、next-env.d.ts
を変更したくなるかもしれませんが、このファイルは自動生成されるため、変更は上書きされます。代わりに、新しいファイル(例:new-types.d.ts
)を作成し、tsconfig.json
で参照してください:
{
"compilerOptions": {
"skipLibCheck": true
//...省略...
},
"include": [
"new-types.d.ts",
"next-env.d.ts",
".next/types/**/*.ts",
"**/*.ts",
"**/*.tsx"
],
"exclude": ["node_modules"]
}
バージョン変更履歴
バージョン | 変更内容 |
---|---|
v15.0.0 | TypeScriptプロジェクト用のnext.config.ts サポートが追加されました。 |
v13.2.0 | 静的に型付けされたリンクがベータ版で利用可能になりました。 |
v12.0.0 | より高速なビルドのためにSWCがデフォルトでTypeScriptとTSXをコンパイルするようになりました。 |
v10.2.1 | tsconfig.json で有効にするとインクリメンタル型チェックのサポートが追加されました。 |