TypeScript入門実践編③Nuxt(Vue)+TypeScriptでデモを作ってみた!

TypeScript入門実践編TypeScriptでデモを作ってみた!シリーズ第3弾はNuxt(Vue)+TypeScript。Reactと並んでよく比較される、もうひとつの人気UIライブラリ、Vueをベースにしたフレームワークです。前回のNext.js(React)と同じフルスタック構成ですが、今回はVueならではの書き方や考え方にも触れながら進めていきます。
※この記事では、Nuxt 4(Vue 3)を対象にしています

この記事の対象読者
- ①②(Laravel、Next.js)を読んで、Vueとの違いを知りたい人
- Reactは触ったことがあるが、Vueは触ったことがない人
- 「TypeScript=Next.js/React」というイメージはあるが、Vue・Nuxt側も実際に手を動かしてみたい人
- 前回記事(20選・4つ構成比較)を読んで、実際の構築手順を知りたい人
この記事のゴール
この記事のゴールは、①②と構成同じく、TypeScriptとNuxtを使った、ごくシンプルな商品編集ページの制作です。表示して、保存を押すと更新される、それだけ。MySQLの商品テーブル(products)は、①で作成したts_demoをそのまま流用します。機能を絞ることで、①②との構成そのものの違いに集中できるようにしています。
Nuxt(Vue)、Next.js(React)の基礎知識
Nuxtとは、Vueとは
Vue(ビュー)は、2014年にアメリカで、当時Google社員だったEvan You氏が個人開発した、SPA(シングルページアプリケーション)向けのMITライセンス・オープンソースJavaScriptライブラリです。現在も法人化されておらず、創始者Evan You氏率いるコアチームが運営を続けています。
Nuxt(ナクスト)は、2016年にフランスで、Alexandre・Sébastien Chopin兄弟が個人開発した、Vueをベースとするフルスタック(サーバー側・画面側を一体で扱う)のMITライセンス・オープンソースフレームワークです。開発初期のミートアップにEvan You氏も登壇するなど、両者は現在も緊密な関係にあります。後に会社化(NuxtLabs)され、2025年にVercel社(Next.jsの開発元)に合流しました。
Vueの語源は、フランス語で「視点」を意味する"vue"に由来すると言われています。Nuxtは、「Vue版のNext.jsを作る」というチャレンジから生まれ、Nextのつづりを一文字変えたものと言われています。
「NuxtはVueベース」「Next.jsはReactベース」という親子関係です。
Vueのバージョン
| Vueのバージョン | リリース年(終了年) | 2026年の位置づけ | 説明 |
|---|---|---|---|
| Vue 1.0 | 2015年(2016年に終了) | ほぼ現存せず | 日本語書籍もほぼ出ていない、普及前の過渡期バージョン |
| Vue 2 | 2016年(2023年12月EOL) | 現役で稼働中の現場が多い | 日本での実質普及は2017〜2018年頃から。EOL済みだが、システム耐久年数の観点ではまだ現役世代。保守案件で今も出会う可能性が高い |
| Vue 3 | 2020年9月〜(現行) | 新規開発の主流 | 新規プロジェクトはVue 3一択。ただしVue 2案件と同時並行で存在している状況 |
2026年現在の最新バージョンはVue 3です。リリースから約6年が経ち、機能追加も落ち着いた安定バージョンといえます。
ただし、これは「Vue 2の現場がもう無い」という意味ではありません。実務ではVue 3の新規案件だけでなく、Vue 2の保守案件に出会う可能性も十分にあります。
問題は、Vue 2とVue 3の違いがどれくらいあるか、です。書き方の土台(Options API中心かComposition API中心か)や、状態管理の標準ライブラリ(Vuex/Pinia)が変わっているため、「Vueを触ったことがある」というだけでは不十分で、配属先がどちらのバージョンかによって、追加の学習が必要になる場合がある、という点は覚えておく必要があります。
Nuxtのバージョン
| Nuxtのバージョン | リリース年(終了年) | 対応Vueバージョン | 2026年の位置づけ | 説明 |
|---|---|---|---|---|
| Nuxt 1.0 | 2018年1月(同年中に終了) | Vue 2 | ほぼ現存せず | Nuxt 2への移行がすぐに始まり、短命だった |
| Nuxt 2 | 2018年(2024年6月30日EOL) | Vue 2 | 現役で稼働中の現場が多い | Nuxtを主流フレームワークとして定着させた世代。EOL済みだが、この世代で構築されたシステムは今もまだ現役の耐用年数内 |
| Nuxt 3 | 2022年11月(2026年7月31日EOL) | Vue 3 | まさに今月サポート終了を迎える節目 | Vue 3ベースへの全面刷新。TypeScript標準対応 |
| Nuxt 4 | 2025年7月〜(現行) | Vue 3 | 新規開発の主流 | リリースから約1年、Nuxt 5への橋渡し的なメジャーバージョン |
2026年現在の最新バージョンはNuxt 4です。ただしリリースからまだ1年ほどで、Vue 3(6年)ほどの枯れ具合ではなく、現在進行形でアップデートが重ねられている段階です。
Nuxt 2も、Vue 2と同じ理由(実質普及期から数えてまだ耐用年数の範囲内)で、保守案件として現場に残っている可能性が十分にあります。加えて、Nuxt 3は2026年7月31日にEOLを迎えたばかり(まさに今)なので、「Nuxt 2・Nuxt 3・Nuxt 4が同時に現場に混在している」状況が、Vue以上に複雑だといえます。
Nuxt 2→3の境目はVueのメジャーバージョンも変わる(Vue 2→3)大きな断絶ですが、Nuxt 3→4はVue側のバージョンは変わっていないため、この2つの移行の重さは全く違います。配属先が何のバージョンかによって、必要な学習量が大きく変わる点は、Vue以上に意識しておく必要がありそうです。
React・Vueの実装方法の違い(日本の現場あるある)
Reactは、JSファイルの中にHTMLのような書き方(JSX)を混ぜて書きます。Vueは、<template>・<script>・<style>という3つの区画が最初から用意された、1つの.vueファイルで画面を作ります。
ReactとVueのファイルの中身の違いをわかりやすくするために、シンプルな商品詳細画面を実装するとこのようなイメージになります。(JSとCSSは別ファイルで書くのが推奨です)
<style scoped>
/* .cardクラス:通常時の文字色 */
.card {
color: gray;
}
/* .activeクラス:確認済みの時に追加される文字色 */
.active {
color: blue;
}
</style>
<script setup>
import { ref } from 'vue';
// 商品データ(初期値は仮のデータ)
const product = ref({ name: 'ボールペン' });
// 確認済みかどうかの状態
const isActive = ref(false);
// ボタン押下時の処理
function handleClick() {
isActive.value = !isActive.value;
alert('確認しました');
}
</script>
<template>
<!-- 確認済みならactiveクラスが付く -->
<div class="card" :class="{ active: isActive }">
<p>{{ product.name }}</p>
<button @click="handleClick">確認</button>
</div>
</template>import { useState } from 'react';
export default function ProductDetail() {
// 商品データ(初期値は仮のデータ)
const [product] = useState({ name: 'ボールペン' });
// 確認済みかどうかの状態
const [isActive, setIsActive] = useState(false);
// ボタン押下時の処理
function handleClick() {
setIsActive(!isActive);
alert('確認しました');
}
return (
// JSXの外側(通常のJSコメント)
<div className={`card ${isActive ? 'active' : ''}`}>
{/* JSXの内側(中括弧で囲んだコメント) */}
<p>{product.name}</p>
<button onClick={handleClick}>確認</button>
<style>{`
/* .cardクラス:通常時の文字色 */
.card {
color: gray;
}
/* .activeクラス:確認済みの時に追加される文字色 */
.active {
color: blue;
}
`}</style>
</div>
);
}Vueは<style>・<script>・<template>が明確にブロック分けされていて、コメントもそれぞれHTML・JS・CSSの通常の書き方がそのまま使えます。Reactは.jsxファイル全体が最初からJSファイルで、専用の区画という概念がありません。<style>タグはただのHTML出力で、Vueのscopedのような自動スコープ分離機能はなく、CSS Modules等の別ライブラリが必要になります。
手順
| 1 | テーブル作成 | ts_demoデータベースにproductsテーブルを作成し、サンプルデータを投入 | SQL |
| 2 | プロジェクト作成 | npm create nuxt@latestでdemo_nuxt_tsを作成(TypeScript、Nuxt 4等を選択) | npm |
| 3 | mysql2インストール・DB接続設定 | npm install mysql2、接続情報を.envに記載し、接続プールを作成 | npm |
| 4 | フォルダとファイルをつくる | 今回の商品編集機能に必要な、フォルダとファイルを作成 | ー |
| 5 | データ取得処理を実装 | server/api内でmysql2を使いSELECT | コードエディタ |
| 6 | データ更新処理を実装 | server/api内でmysql2を使いUPDATE | コードエディタ |
| 7 | 編集ページとフォームを作成 | pages内に商品編集ページを作成し、フォームを実装 | コードエディタ |
| 8 | 確認ダイアログを実装 | 送信前に確認ダイアログを出す処理を実装 | コードエディタ |
| 9 | 動作確認(確認ダイアログ) | ダイアログでOKを押した場合のみ更新されることを確認 | ブラウザ |
事前準備
実装に入る前に以下の準備をお願いします。
1.MySQL(MariaDB)のインストール
2.VS Codeのインストール
3.Node.jsのインストール(バージョン確認:node -v、npm -v)。
※Nuxt 4を使うため、Node.js 20.19以上、または22.12以上が必要です
実装手順解説
1.テーブル作成
まず、productsテーブルを作成します。①または②ですでに作成済の方はスキップしてください。
1.お使いのMySQLクライアント(HeidiSQL、phpMyAdmin、コマンドラインのmysql等)で、以下のSQLを実行します。
CREATE DATABASE IF NOT EXISTS ts_demo;
USE ts_demo;
CREATE TABLE products (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
price VARCHAR(255) NOT NULL
);
INSERT INTO products (name, price) VALUES
('ボールペン', '150'),
('ノート', '300');2.実行後、productsテーブルに2件のデータが入っていれば成功です。
2.プロジェクト作成
Nuxtは①のLaravelと違い、XAMPP(Apache)を経由しないので、C:\xampp\htdocsの中に置く必要はありません。今回はC:\projectsの中に、demo_nuxt_tsという名前でプロジェクトを作成します。
手順
1.VS Codeを開きます。
2.「ファイル」→「フォルダーを開く」を選択し、C:\projectsを指定して開きます。
3.上部メニューの「ターミナル」→「新しいターミナル」を選択し、ターミナルを開きます。

4.以下のコマンドを実行します。
npm create nuxt@latest demo_nuxt_ts -- -t v4npm createは、npm(Node.jsのパッケージ管理ツール)に組み込まれている、プロジェクトの雛形を作成するためのコマンドです。①のComposerでlaravel/laravelという雛形をダウンロードしたのと、同じ役割です。
nuxt@latestは、Nuxt公式が提供している「プロジェクト作成ツール」を、常に最新版で実行する、という指定です。@latestを付けない場合、古いキャッシュが使われてしまうことがあるため、@latestを付けておくことで、常に最新のツールを実行できます。
demo_nuxt_tsは、今回作成するプロジェクトのフォルダ名です。
-- -t v4の部分は、少し特殊な書き方です。--は「ここから先は、npm自体へのオプションではなく、実行するツール(今回はNuxtのプロジェクト作成ツール)へ渡すオプションです」という区切りの記号です。-t v4は、そのツールに対する「テンプレートはv4(Nuxt 4)を使ってください」という指定です。この指定がないと、テンプレートによってはNuxt 3が作成されてしまう場合があるため、明示的に指定しています。
実行すると、プロジェクトの構成についていくつか質問が表示されます。実際の出力を貼り付けてください。
以下のように設定していきます。
PS C:\projects> npm create nuxt@latest demo_nuxt_ts -- -t v4
npm warn "v4" is being parsed as a normal command line argument.
npm warn Unknown cli config "--t". This will stop working in the next major version of npm.
> npx
> create-nuxt demo_nuxt_ts v4
.d$b.
i$$A$$L .d$b
.$$F` `$$L.$$A$$.
j$$' `4$$:` `$$.
j$$' .4$: `$$.
j$$` .$$: `4$L
:$$:____.d$$: _____.:$$:
`4$$$$$$$$P` .i$$$$$$$$P`
Need to install the following packages:
create-nuxt@3.37.0
Ok to proceed? (y) ←yを入力 (1)
┌ Welcome to Nuxt!
│
◇ Which template would you like to use?
│ minimal – Minimal starter with a single app.vue. ←minimalを選択 (2)
│
◇ Which package manager would you like to use?
│ npm ←npmを選択 (3)
│
◇ Initialize git repository?
│ Yes ←Yesを選択 (4)
│
◇ Would you like to browse and install modules?
│ No ←Noを選択 (5)
│
◆ Are you interested in participating?
│ No ←Noを選択 (6)
│
└ ✨ Nuxt project has been created with the minimal template.
╭── 👉 Next steps ─────╮
│ │
│ › cd demo_nuxt_ts │
│ › npm run dev │
│ │
╰──────────────────────╯各選択肢の意味は以下のとおり。
| # | 何を聞かれているか | 選択内容 | 選んだ理由 |
|---|---|---|---|
| 1 | パッケージのインストールを許可するか | y | create-nuxt本体をまだ取得していないため、初回は必ずyが必要 |
| 2 | プロジェクトのテンプレート(雛形の種類)をどれにするか | minimal | 最小構成のテンプレート。プロジェクトの初期調査段階では、まず素の状態から必要な機能を見極めるのが基本方針のため。content(コンテンツ管理向け)やui(UIライブラリ同梱)は、それらの用途が既に決まっている場合に選ぶテンプレートなので、通常はminimalから始めるのが妥当 |
| 3 | どのパッケージマネージャーを使うか | npm | Node.js標準で最初から使えるツールのため、特別な理由がなければnpmを選ぶのが基本。既にプロジェクト内でpnpmやyarnを使う方針が決まっている場合は、その旨に合わせて選択してください |
| 4 | このプロジェクト用にGitリポジトリを初期化するか | Yes | ソースコードの変更履歴を管理する基本作業のため、通常はYesを選ぶ。ただし、既に別の場所でGit管理された親フォルダの中にプロジェクトを作る場合など、二重管理になってしまうケースではNoを選んでください |
| 5 | 作成時点で追加のNuxtモジュールをインストールするか | No | まずは最小構成で立ち上げ、必要になったモジュールをその都度追加していくのが基本方針。認証機能やUIライブラリなど、要件が最初から明確に決まっている場合は、ここでYesを選び該当モジュールを追加しても問題ありません |
| 6 | Nuxt開発チームへ、匿名の利用状況データを送信するか | No | 外部への情報送信を必要最小限に留める方針のため。送信内容自体は匿名の統計情報なので、参加してもセキュリティ上の実害はありません |
インストールが完了すると、以下のフォルダが生成されます。

app/pages/フォルダがファイルベースルーティング(ファイル名・フォルダ構造がそのままURLになる仕組み)の起点、public/が画像等の静的ファイル置き場、node_modules/が依存パッケージ、package.jsonが①でいうcomposer.jsonに相当する管理ファイルです。nuxt.config.tsやtsconfig.jsonもすでに自動生成されています。今回の商品編集ページの範囲では、この2つを手動で編集する作業は発生しません(実務では、モジュール追加やパス設定などでnuxt.config.tsを編集する場面は多くあります)。
5.正しく作成できたか確認します。以下のコマンドを実行してください。
npm run dev7.ブラウザでhttp://localhost:3000にアクセスし、Nuxtの初期画面が表示されれば、プロジェクト作成は成功です。

3.mysql2インストール・DB接続設定
商品データをMySQLから取得・更新できるように、mysql2パッケージを導入します。
手順
1.前の手順で実行したnpm run devは動かしたままにしたいので、新しくターミナルを開きます。ターミナルパネル右上の「+」アイコンをクリックするか、`Ctrl + Shift + ``を押してください。プロジェクトのフォルダを開いた状態のまま新しいターミナルが開くので、フォルダを移動する必要はありません。
2.新しいターミナルで、demo_nuxt_tsに移動して以下を実行します。
cd demo_nuxt_ts
npm install mysql2以下のようにmysql2パッケージがダウンロード、インストールされます。

3.DB接続に必要なフォルダとファイルを作成します。

DB接続に必要なフォルダとファイルを作成します。プロジェクトのルート(demo_nuxt_ts直下)にserverフォルダを作成し、その中にutilsフォルダを作成、さらにその中にdb.tsという空のファイルを作成してください。server/やutils/という名前自体はNuxtの規約ですが、minimalテンプレートには最初から用意されていないため、今回は自分で作る必要があります(テンプレートによっては、あらかじめ用意されている場合もあります)。
4..env、DB接続情報を記載します。①と同じts_demoデータベースです
DB_HOST=127.0.0.1
DB_PORT=3306
DB_NAME=ts_demo
DB_USER=root
DB_PASSWORD=5.server/utils/db.tsに、以下を記述します。
import mysql from 'mysql2/promise';
const pool = mysql.createPool({
host: process.env.DB_HOST,
port: Number(process.env.DB_PORT),
database: process.env.DB_NAME,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
});
export default pool;これは、DB接続を読み込むコードを共通化しているお決まりのコードです。後述するコードでこのファイルをインポートします。
4.フォルダとファイルをつくる
今回の商品編集機能に必要なファイルを作成します。今回はshared/は使わないので、app/とserver/だけ用意します。
Nuxtには、フォルダの構造そのものがURLのルーティングになる、ファイルベースルーティングという仕組みがあります。
+ DBアクセスの処理は、server/repository/という、Nuxtの自動import対象外の、独自に作るフォルダにまとめます。今回はこの構成(repository)を採用しますが、これはNuxt公式の仕様ではなく、複数の画面から同じDB処理を呼び出す可能性を見据えた、今回の設計方針です。
手順
1.以下の図のようにフォルダとファイルを作成してください。
app/pages/products/[id]/edit.vue← 画面server/api/products/[id].get.ts← 取得の受付server/api/products/[id].post.ts← 更新の受付server/repository/products.ts← SQLを実行する本体server/utils/db.ts← DBへの接続口

POINT
Nuxt 4の3層構造
Nuxt 4は、app/(フロントエンド)・server/(バックエンド)・shared/(両方から使える共通領域)という3層構造を基本とした設計になっています。shared/は、サーバー・クライアント両方で同じ型やロジック(例:フォームの入力チェック)を使いたくなった時に追加する場所で、今回のような小さな機能では使わないことも普通です。
5.データ取得処理を実装
server/repository/products.ts、server/api/products/[id].get.tsの2つを実装します。
手順
1.server/repository/products.tsに、以下を記述します。
import pool from '~~/server/utils/db';
export async function getProduct(id: string) {
const result = await pool.query('SELECT * FROM products WHERE id = ?', [id]);
const rows = result[0];
const product = rows[0];
return product;
}pool.query(...)は、mysql2ライブラリのPoolクラスのインスタンスメソッドで、戻り値はPromiseです。実行結果は[取得データ本体, フィールド情報]という2つの要素を持つ配列で返ってくるため、1番目(result[0])が実際のデータです。そのデータ本体も、複数件に対応できるよう配列の形になっているため、rows[0]で1件目だけを取り出しています。
2.server/api/products/[id].get.tsに、以下を記述します。
import { getProduct } from '~~/server/repository/products';
export default defineEventHandler(async (event) => {
const id = getRouterParam(event, 'id');
return await getProduct(id);
});getRouterParam(event, 'id')は、URLの[id]部分(例:/api/products/1の「1」)を取り出す、Nuxtが提供する関数です。defineEventHandlerは、この関数がサーバーのリクエストを処理するハンドラーであることを示す、Nuxtの構文です。この記述で囲むことで、Nuxtが自動的にAPIエンドポイントとして認識します。
3.ブラウザで以下のURLにアクセスします。
http://localhost:3000/api/products/1
4.1件目の商品(ボールペン)のデータがJSON形式で表示されたら成功です。

6.データ更新処理を実装
server/repository/products.ts、server/api/products/[id].post.tsの2つを実装します。
手順
1.server/repository/products.tsに、更新用の関数を追加します。
import pool from '~~/server/utils/db';
// 商品を1件取得する
export async function getProduct(id: string) {
const result = await pool.query('SELECT * FROM products WHERE id = ?', [id]);
const rows = result[0];
const product = rows[0];
return product;
}
// 商品を1件更新する
export async function updateProduct(id: string, name: string, price: string) {
await pool.query('UPDATE products SET name = ?, price = ? WHERE id = ?', [name, price, id]);
}updateProduct関数を追加しました。pool.query(...)のUPDATE文は、SQLの?の部分に、配列で渡したname・price・idが、順番に安全に埋め込まれます。
2.server/api/products/[id].post.tsに、以下を記述します。
import { updateProduct } from '~~/server/repository/products';
export default defineEventHandler(async (event) => {
const id = getRouterParam(event, 'id');
const body = await readBody<{ name: string; price: string }>(event);
await updateProduct(id, body.name, body.price);
return { message: '更新しました' };
});readBody(event)は、リクエストとして送られてきたデータ(今回は商品名・価格)を取り出す、Nuxtが提供する関数です。body.name・body.priceという形で、送られてきたデータをまとめて受け取ります。
7.編集ページとフォームを作成
app/pages/products/[id]/edit.vueに、表示と保存フォームを実装します。
手順
1.既存のapp/app.vueを開き、中身を以下に書き換えます。
<template>
<NuxtPage />
</template><NuxtPage />は、pages/フォルダの中から、現在のURLに対応するファイルを自動的に選んで表示する、Nuxtの仕組みです。minimalテンプレートの初期状態では、この差し込みがされていないため、書き換えが必要です。
2.app/pages/products/[id]/edit.vueに、以下を記述します。
<script setup lang="ts">
const route = useRoute();
const id = route.params.id as string;
const { data: product } = await useFetch(`/api/products/${id}`);
async function handleSubmit() {
await $fetch(`/api/products/${id}`, {
method: 'POST',
body: { name: product.value.name, price: product.value.price },
});
}
</script>
<template>
<div>
<h1>商品編集</h1>
<input v-model="product.name" />
<input v-model="product.price" />
<button @click="handleSubmit">保存</button>
</div>
</template>useFetchは、画面表示時にAPI(server/api/products/[id].get.ts)からデータを取得する、Nuxtが提供する関数です。今回はNuxt公式サンプルでもよく見られるように、ページから直接useFetchを利用しています。実務ではComposable(app/composables/)やAPI通信専用の層を挟む設計も広く使われており、どちらが唯一の正解というわけではありません。v-modelは、入力欄の値とproductの値を双方向に結びつける、Vueの記法です。②のReactではdefaultValueで初期値を表示するだけでしたが、Vueのv-modelは入力するたびにproductの値も自動的に更新されます。
handleSubmit関数は、保存ボタンが押された時に、$fetchで更新API(server/api/products/[id].post.ts)を呼び出します。
3.ブラウザで以下のURLにアクセスします。
http://localhost:3000/products/1/edit
4.商品名と価格が、入力欄に表示されたら成功です。

5.値を書き換えて「保存」を押し、リロードしても変更が反映されていれば成功です。
8.確認ダイアログを実装
最後に確認ダイアログを実装します。
手順
1.app/pages/products/[id]/edit.vueのhandleSubmit関数を、以下のように書き換えます。
<script setup lang="ts">
const route = useRoute();
const id = route.params.id as string;
const { data: product } = await useFetch(`/api/products/${id}`);
async function handleSubmit() {
const isConfirmed = confirm('この内容で保存しますか?');
if (!isConfirmed) {
return;
}
await $fetch(`/api/products/${id}`, {
method: 'POST',
body: { name: product.value.name, price: product.value.price },
});
}
</script>
<template>
<div>
<h1>商品編集</h1>
<input v-model="product.name" />
<input v-model="product.price" />
<button @click="handleSubmit">保存</button>
</div>
</template>2.画面で保存をおすと確認ダイアログが表示されたら成功。

9.動作確認(確認ダイアログ)
1.ブラウザでhttp://localhost:3000/products/1/editにアクセスします。
2.商品名または価格を書き換えます。
3.「保存」ボタンを押します。
4.「この内容で保存しますか?」という確認ダイアログが表示されることを確認します。
5.「キャンセル」を押した場合、保存されずに元の画面のままであることを確認します。
6.もう一度「保存」を押し、今度は「OK」を押します。
7.リロードして、書き換えた内容が反映されていれば成功です。
さいごに
今回は、Reactと並ぶ人気UIライブラリのVueをベースにしたフルスタックフレームワーク、Nuxtを使って、TypeScriptで商品編集ページを実際に構築してみました。①②同様、フロント・サーバーの両方でTypeScriptの型を共有しながら実装できる点は、Nuxtでも変わりません。
次回は、④NestJS+Reactに進みます。同じproductsテーブル、同じ商品編集ページという題材で、今度はフロントとバックエンドが完全に分離した「API分離型」の構成でTypeScriptがどう使われるか、引き続き検証していきます。


