TypeScript
Next.js は、React アプリケーションを構築するための TypeScript ファースト開発体験を提供します。
必要なパッケージを自動的にインストールし、適切な設定を構成するための組み込みの TypeScript サポートが付属しています。
エディター用の TypeScript Plugin もあります。
🎥 視聴: 組み込みの TypeScript プラグインについて学ぶ → YouTube (3分)
新しいプロジェクト
create-next-app
は、デフォルトで TypeScript を搭載しています。
npx create-next-app@latest
既存のプロジェクト
ファイルを.ts
/ .tsx
にリネームすることでプロジェクトに TypeScript を追加できます。next dev
と next build
を実行すると、必要な依存関係が自動的にインストールされ、推奨設定オプションが含まれる tsconfig.json
ファイルが追加されます。
既に jsconfig.json
ファイルがあった場合、古い jsconfig.json
から paths
コンパイラオプションを新しい tsconfig.json
にコピーし、古い jsconfig.json
ファイルを削除してください。
また、より良い型推論のために next.config.ts
を next.config.js
の代わりに使うことをお勧めします。
TypeScript プラグイン
Next.js はカスタム TypeScript プラグインと型チェッカーを含んでおり、VSCode などのコードエディターが高度な型チェックやオートコンプリートに使用できます。
VS Code でプラグインを有効にするには:
- コマンドパレットを開く(
Ctrl/⌘
+Shift
+P
) - 「TypeScript: Select TypeScript Version」を検索
- 「Use Workspace Version」を選択
これでファイルを編集する際に、カスタムプラグインが有効になります。next build
を実行する際には、カスタム型チェッカーが使用されます。
プラグインの機能
TypeScript プラグインは以下の支援 が可能です:
- segment config options に対して無効な値が渡された場合の警告
- 利用可能なオプションと文脈に応じたドキュメントの表示
use client
指令が正しく使用されていることの確認- クライアントフック(
useState
など)が Client Components のみで使用されることの確認
知っておくと良いこと: 今後、さらなる機能が追加される予定です。
最低 TypeScript バージョン
TypeScript の少なくとも v4.5.2
を使用することを強く推奨します。これにより、import 名に対する型修飾子やパフォーマンスの向上などの構文機能が利用できます。
Next.js の設定における型チェック
next.config.js での型チェック
next.config.js
ファイルを使用する際、以下のように JSDoc を使用して IDE 内で型チェックを追加できます:
// @ts-check
/** @type {import('next').NextConfig} */
const nextConfig = {
/* config options here */
}
module.exports = nextConfig
next.config.ts での型チェック
Next.js の設定で next.config.ts
を使用することで、TypeScript と型のインポートを利用できます。
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
/* config options here */
}
export default nextConfig
注意:
next.config.ts
におけるモジュール解決は、現在CommonJS
に限定されています。これにより、ESM のみのパッケージを読み込むときに互換性の問題が発生する可能性があります。
静的型チェックされたリンク
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 がエディターで無効なリンクについてフィードバックを提供できるようにします。
現在、実験的にサポートされているのは、動的セグメントを含む任意の文字列リテラルです。リテラルでない文字列の場合、現在は Route
として href
を手動でキャストする必要があります:
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
をチェックし、エディターで無効なリンクについてフィードバックを提供します。
エンドツーエンドの型安全性
Next.js の app router は、強化された型安全性を持っています。これには以下が含まれます:
- フェッチ関数とページ間のデータのシリアル化なし: サーバーでコンポーネント、レイアウト、およびページ内で
fetch
できます。このデータはクライアントサイドで消費するためにシリアル化(文字列に変換)する必要はありません。代わりに、app
ではデフォルトで server component を使用しているため、Date
、Map
、Set
などの値を追加の手順なしで使用できます。以前は、Next.js 固有の型を使って、サーバーとクライアント間の境界を手動で型定義する必要がありました。 - コンポーネント間のデータフローの簡素化: root レイアウトを採用し
_app
が削除されたことで、コンポーネントとページ間のデータフローが視覚化しやすくなりました。以前は、個々のpages
と_app
間のデータフローは型付けが困難で、混乱を招くバグが発生する可能性がありました。App router でのコロケーションされたデータフェッチによって、これはもはや問題ではありません。
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 や型安全なクエリビルダーを使用することで達成できます。
非同期 server component の TypeScript エラー
非同期 server component を TypeScript とともに使用するには、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 間のデータ受け渡し
server component と client component の間で props 経由でデータを渡す際、そのデータはブラウザでの使用のためにシリアル化(文字列に変換)されますが、特別な型付けは必要ありません。これは、他のコンポーネント間で props を渡す場合と同じ方法で型付けされます。
さらに、未レンダリングのデータがサーバーとクライアント間を渡らないため、シリアル化されるコードは少なくなります(サーバーにとどまります)。これは server component のサポートがあってこそ可能です。
パスエイリアスと 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
オプションを有効にします:
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
typescript: {
// !! WARN !!
// あなたのプロジェクトに型エラーがある場合でも
// 本番ビルドが正常に完了することを許可します。
// !! WARN !!
ignoreBuildErrors: true,
},
}
export default nextConfig
知っておくと良いこと: 自分で TypeScript エラーを
tsc --noEmit
でチェックした後にビルドすることができます。これは、デプロイ前に TypeScript エラーをチェックしたい CI/CD パイプラインにとって便利です。
カスタム型宣言
カスタム型を宣言する必要がある場合、next-env.d.ts
を変更したくなりますが、このファイルは自動生成されるため、変更はすべて上書きされます。新しいファイルを作成し、たとえば new-types.d.ts
と名付け、それを 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.0 | TypeScript プロジェクトに対するnext.config.ts のサポートが追加されました。 |
v13.2.0 | 静的型チェックされたリンクがベータ版で利用可能です。 |
v12.0.0 | SWC がデフォルトで使用され、ビルドが高速化されるように TypeScript と TSX のコンパイルに使用されます。 |
v10.2.1 | tsconfig.json で有効にされた場合、インクリメンタル型チェック のサポートが追加されました。 |