フロントエンドの勉強を始めてしばらく経ったころ、「Next.jsをTypeScriptで書くといい」という話をよく目にするようになりました。ただ、いざ調べてみると情報が多すぎてどこから手をつければいいのかわからない。この記事は、そのときの自分と同じような状況にいる初心者の方に向けて、実際に動かしながら学べるようにまとめたものです。
この記事で学べること
- Next.jsとTypeScriptを組み合わせるメリット
- 2026年2月時点のバージョン事情(Next.js 15 / 16)
- プロジェクトの環境構築手順(create-next-app)
- TypeScriptの基本的な型付けの書き方
- App Routerでのページ・コンポーネント作成
- 実践:型安全なデータフェッチの実装例
Next.jsとTypeScriptを組み合わせるメリット
「なぜこの2つを組み合わせるのか」というところから整理します。最初は「JavaScriptだけじゃダメなの?」と思うかもしれませんが、実際に触ってみると納得できます。
Next.jsが選ばれる理由
Next.jsはReactをベースとしたフレームワークで、サーバーサイドレンダリング(SSR)、静的サイト生成(SSG)、ファイルベースルーティング、API Routes(Route Handlers)、自動コード分割、そしてTypeScriptサポートなど、モダンWeb開発に必要な機能がひとまとめになっています。
Next.jsはサーバーサイドでReactアプリケーションをレンダリングできるため、ユーザーにはすぐに表示されるコンテンツが提供され、SEOにも有利です。 一言でいうと「速くてSEOに強いReactアプリが作れるフレームワーク」です。
TypeScriptを一緒に使うメリット
Next.jsはTypeScriptを公式にサポートしており、create-next-appで新しいプロジェクトを作成するときにTypeScriptを選ぶだけで、必要なパッケージのインストールと適切な設定が自動で行われます(既存プロジェクトでも、.ts/.tsxを追加してnext dev/buildを実行すると設定が自動生成されます)。
またApp Router(React Server Components前提)では、サーバー上で動くコンポーネント内で直接データ取得を書けるため、UIとデータ取得を近い場所に置きやすく、型をつけて安全に保ちやすいのも相性が良いポイントです。
2026年2月時点のバージョン事情
公式発表ベースだと、Next.js 15は2024年10月21日に「安定版(stable)」としてリリースされています。Next.js 16は2025年10月21日にリリースされています。
「今から始めるならどれがいい?」は状況次第です。Next.js 15系は広く使われており学習情報も多い一方、Next.js 16では開発・ビルドの既定がTurbopackになるなど、前提が変わっている部分があります。この記事では、学習しやすい形としてNext.js 15系で説明しつつ、必要に応じて16系の注意点も補足します。
なおNext.js 15.5では、Typed Routes(型付きルート)が「typedRoutes: true」フラグで安定機能として提供されています。これを有効にすると、ファイル構造からルートの型が生成され、<Link> が存在しないパスを指していないかをコンパイル時に検出できるようになります(Turbopackでも動く実装に改善されています)。
環境構築:まずは動くところまで
「環境構築で詰まってやる気をなくした」という話はよく聞きます。ここはできるだけ丁寧に説明します。
必要なもの(Node.jsのインストール確認)
Next.jsを動かすにはNode.jsが必要です。Next.js 15はNode.js 18.18.0以上(または19.8.0以上、20以上)が条件とされており、迷ったらNode.js 20(LTS系)を入れておくと安全です。なおNext.js 16はNode.js 20.9.0以上が必須です。
Node.jsが入っていない場合はまず公式サイトからLTS版をインストールしてください。インストール後はターミナルで以下を実行して確認しましょう。
node --version
npm --version
どちらもバージョン番号が表示されれば準備OKです。
create-next-appでプロジェクト作成
Next.jsではcreate-next-appという公式ツールを使用して簡単にプロジェクトを作成できます。 以下のコマンドを実行すると、対話形式でプロジェクトの設定を進められます。
npx create-next-app@latest my-app
いくつか質問が出てきます。初心者のうちは以下のように答えておくとスムーズです。
Would you like to use TypeScript? → Yes
Would you like to use ESLint? → Yes
Would you like to use Tailwind CSS? → Yes(お好みで)
Would you like to use `src/` directory? → No(最初はシンプルにしておく)
Would you like to use App Router? → Yes(推奨)
Would you like to customize the default import alias (@/*)? → No
プロジェクトが作成されたら、ディレクトリに移動して開発サーバーを起動します。
cd my-app
npm run dev
開発サーバーを起動すると、ファイルを変更した際に自動的にブラウザが更新されます。ポートはデフォルトでlocalhost:3000です。
ブラウザで http://localhost:3000 にアクセスしてNext.jsのデフォルト画面が出ればひとまず成功です。
プロジェクトの構成を把握する
作成されたファイルがたくさんあって最初は戸惑いますが、最低限おさえておけばいい部分は以下のとおりです。
my-app/
├── app/
│ ├── layout.tsx ← 全ページ共通のレイアウト
│ ├── page.tsx ← トップページ(/)
│ └── globals.css ← グローバルCSS
├── public/ ← 画像など静的ファイル置き場
├── next.config.ts ← Next.jsの設定ファイル(TypeScript対応)
└── tsconfig.json ← TypeScriptの設定ファイル
Next.js 15では next.config.ts(TypeScript形式の設定ファイル)がサポートされており、NextConfig 型によるオートコンプリートと型安全なオプション設定ができます。
TypeScriptの基本をNext.jsで学ぶ
TypeScriptを別途がっつり勉強してからNext.jsをやろうとすると、時間がかかってモチベーションが続かないことが多いです。実際のNext.jsコードの中で必要な型の書き方を覚えていくほうが身につきやすいでしょう。
型アノテーション:変数と関数に型をつける
型アノテーションとは、変数や関数が扱う型(文字列・数値など)をTypeScriptに明示的に伝える記述のことです。 具体的には以下のように書きます。
// 変数への型指定
const userName: string = "にゃんち"
const age: number = 25
const isLoggedIn: boolean = true
// 関数への型指定(引数と戻り値)
const greet = (name: string): string => {
return `こんにちは、${name}さん!`
}
// 呼び出し
console.log(greet("にゃんち")) // → こんにちは、にゃんちさん!
「この変数は文字列だよ」「この関数は文字列を返すよ」ということを明示するのが型アノテーションです。書いておくと間違った型を渡したときにエディタが教えてくれます。
インターフェースでオブジェクトの型を定義する
インターフェースとは、オブジェクトがどんなプロパティを持つかを定義するTypeScriptの機能です。 Next.jsでAPIからデータを取得するとき、このインターフェースが特に役立ちます。
// ユーザー情報の型定義
interface User {
id: number
name: string
email: string
age?: number // ?をつけるとオプショナル(なくてもOK)
}
// 型を使ったコンポーネントの例
const UserCard = ({ user }: { user: User }) => {
return (
<div>
<h2>{user.name}</h2>
<p>{user.email}</p>
</div>
)
}
インターフェースを定義しておくと、オブジェクトに存在しないプロパティを参照しようとしたときにエラーになり、バグを事前に防げます。
App Routerでページとコンポーネントを作る
Next.js 13以降はApp Routerが主流になりました。 App Routerではファイルベースルーティング、レイアウト、React Server Componentsなどが利用できます。 実際にページを作りながら流れを掴んでいきましょう。
新しいページを追加する
App Routerではフォルダ構造がそのままURLになります。たとえば /about というページを作るには以下のようにします。
// app/about/page.tsx
export default function AboutPage() {
return (
<main>
<h1>このサイトについて</h1>
<p>TypeScript × Next.jsで作ったサイトです。</p>
</main>
)
}
これだけで http://localhost:3000/about にアクセスするとページが表示されます。ファイルを置くだけでルーティングが完成するのがNext.jsの強みです。
TypeScript型付きコンポーネントを作る
再利用できるコンポーネントを作るときは、propsの型をインターフェースで定義するのがお作法です。
// components/ArticleCard.tsx
// propsの型定義
interface ArticleCardProps {
title: string
description: string
date: string
imageUrl?: string // 省略可能
}
// 型付きコンポーネント
export default function ArticleCard({
title,
description,
date,
imageUrl,
}: ArticleCardProps) {
return (
<article style={{ border: "1px solid #ccc", padding: "16px", borderRadius: "8px" }}>
{imageUrl && <img src={imageUrl} alt={title} style={{ width: "100%" }} />}
<h2>{title}</h2>
<p>{description}</p>
<small>{date}</small>
</article>
)
}
このコンポーネントをページで使うときは以下のように書きます。
// app/page.tsx
import ArticleCard from "@/components/ArticleCard"
export default function HomePage() {
return (
<main>
<h1>記事一覧</h1>
<ArticleCard
title="TypeScript入門"
description="TypeScriptの基本を学ぼう"
date="2026-02-21"
/>
</main>
)
}
imageUrl は省略可能(?がついているため)ですが、title を渡し忘れたりするとエディタが赤線を引いてすぐ気づけます。これがTypeScriptの恩恵です。
実践:型安全なデータフェッチをNext.jsで実装する
ここが最も実用的なパートです。APIからデータを取ってきて表示するのはWebアプリの基本動作であり、App RouterのServer Componentsを使うと非同期処理がとてもシンプルに書けます。
Server Componentで型安全にデータ取得する
App RouterのServer Componentsでは、サーバー側で動くコンポーネント内で直接データを取得できます。
注意点として、Server ComponentからClient Componentにpropsとして渡す値はシリアライズ可能である必要があります。DateオブジェクトやMapなどはそのまま渡せないケースがあるため、基本は文字列やプレーンオブジェクトに変換して渡すのが安全です(Server Component内だけで使う場合は問題ありません)。
// app/posts/page.tsx
// 投稿データの型定義
interface Post {
id: number
title: string
body: string
userId: number
}
// データ取得関数(サーバー側で実行される)
async function getPosts(): Promise<Post[]> {
const res = await fetch("https://jsonplaceholder.typicode.com/posts?_limit=5")
if (!res.ok) {
throw new Error("データの取得に失敗しました")
}
return res.json()
}
// Server Component(asyncをつけるだけでOK)
export default async function PostsPage() {
const posts = await getPosts() // awaitで直接取得できる
return (
<main>
<h1>投稿一覧</h1>
<ul>
{posts.map((post) => (
<li key={post.id}>
<h2>{post.title}</h2>
<p>{post.body}</p>
</li>
))}
</ul>
</main>
)
}
Post[] という型を定義してあるので、post.title や post.body にアクセスするとオートコンプリートが効きます。存在しないプロパティ(例:post.content)を書こうとするとエラーになります。これが「型安全」の意味するところです。
動的ルーティングで個別ページを作る
投稿の詳細ページなど、IDによって内容が変わるページは動的ルーティングを使います。フォルダ名を [id] のように角括弧で囲むだけで実現できます。
// app/posts/[id]/page.tsx
interface Post {
id: number
title: string
body: string
}
// paramsの型定義
type PageProps = {
params: Promise<{ id: string }>
}
async function getPost(id: string): Promise<Post> {
const res = await fetch(`https://jsonplaceholder.typicode.com/posts/${id}`)
if (!res.ok) throw new Error("データの取得に失敗しました")
return res.json()
}
export default async function PostDetailPage({ params }: PageProps) {
const { id } = await params
const post = await getPost(id)
return (
<main>
<h1>{post.title}</h1>
<p>{post.body}</p>
</main>
)
}
Next.js 15では、動的セグメントの params は「Promiseとして渡される」挙動になっており、async/await(またはReactの use())で取り出すのが公式ドキュメントでも案内されています。互換性のために同期的にアクセスできる挙動も残っていますが、将来的には非推奨になるとされています。
開発を快適にするツールとTips
Turbopackで開発サーバーを高速化する
TurbopackはNext.jsの次世代バンドラー(モジュールをまとめてブラウザで動かせる形に変換するツール)です。Next.js 15では next dev --turbopack で有効化できます。Next.js 16ではTurbopackが next dev と next build の既定になっています(既存プロジェクトでwebpack設定に依存している場合は、16への移行時に注意が必要です)。
Next.js 15での使い方は簡単で、開発サーバー起動時に --turbopack フラグをつけるだけです。
npm run dev -- --turbopack
または package.json のscriptsを書き換えておくと毎回打つ必要がなくなります。
{
"scripts": {
"dev": "next dev --turbopack",
"build": "next build",
"start": "next start"
}
}
補足:Turbopackの本番ビルドも next build --turbopack で使えますが、バージョンによって安定性の扱いが変わっています。Next.js 15.5の時点では「Turbopack Builds(beta)」という位置づけです。まずはdevだけで有効にして、問題がなければbuildにも広げるのが安全です。
よく使うnpmコマンドを覚えておく
# 開発サーバー起動(ファイル変更を自動検知)
npm run dev
# 本番ビルド(デプロイ前に実行)
npm run build
# TypeScriptの型チェックのみ(ビルドせずエラー確認)
npx tsc --noEmit
特に npx tsc --noEmit は、ビルドせずに型エラーだけ確認できるのでコミット前のチェックに便利です。
まとめ:TypeScript × Next.js 入門のポイント
- Next.jsはReactベースのフレームワークで、SSR・SSG・ファイルベースルーティングなどがすぐ使える
- TypeScriptは公式サポートで、create-next-appでプロジェクト作成すれば自動でセットアップされる
- Next.js 15は2024年10月21日、Next.js 16は2025年10月21日にリリース(学習は15でもOKだが、16は前提が変わる点がある)
- Typed RoutesはNext.js 15.5で安定化(
typedRoutes: true)し、<Link>のルートミスをコンパイル時に検出できる - App RouterはServer ComponentでasyncがそのままOKで、データ取得がシンプルに書ける
- インターフェースでpropsやAPIレスポンスに型をつけることで、バグを事前に発見しやすくなる
- 動的ルーティングはフォルダ名を[id]にするだけで実現できる(Next.js 15ではparamsはPromiseとして扱うのが公式案内)
最初は「TypeScriptって難しそう」「Next.jsって設定が多そう」と感じるかもしれません。ただ実際に触ってみると、エラーが出たときにエディタが「ここが違う」と教えてくれるため、むしろJavaScriptだけで書くよりデバッグが楽なくらいです。まずは手を動かしてみるのが一番の近道なので、ぜひ試してみてください。

