Chapter 5: TypeScript 入門
TypeScript は JavaScript に型の仕組みを加えた言語です。
型を明示すると,コードの意図が伝わりやすくなり,バグの早期発見にもつながります。Next.js でも標準的に採用されているため,ここで基礎を押さえておきましょう。
TypeScript を導入する
- 作業用フォルダ(例:
fes-training/javascript/ts-intro)を作成。 - npm プロジェクトを初期化し,TypeScript を追加します。
tsconfig.jsonが生成されます。以下の設定を確認・変更しておきましょう。
{
"compilerOptions": {
"target": "ES2020",
"module": "ES2020",
"moduleResolution": "node",
"outDir": "dist",
"strict": true,
"esModuleInterop": true
},
"include": ["src"]
}
srcフォルダを作り,index.tsを作成します。
type StaffRole = "system" | "design" | "publicity";
interface Staff {
id: number;
name: string;
role: StaffRole;
skills: string[];
}
const members: Staff[] = [
{ id: 1, name: "山田 太郎", role: "system", skills: ["React", "Git"] },
{ id: 2, name: "佐藤 花子", role: "design", skills: ["Figma", "HTML"] },
];
function findMembersByRole(role: StaffRole): Staff[] {
return members.filter((member) => member.role === role);
}
console.log(findMembersByRole("system"));
- コンパイルして実行します。
基本的な型
| 型 | 例 | 説明 |
|---|---|---|
string |
"Hello" |
文字列 |
number |
42 |
数値(整数・小数) |
boolean |
true |
真偽値 |
Array<T> |
string[] |
配列 |
object |
{ name: "Chibafes" } |
オブジェクト |
union |
"draft" \| "published" |
いずれかの値 |
TypeScript は型推論が賢いため,明示しなくても推論されることが多いです。ただし,関数の引数や戻り値には型を付ける習慣を付けましょう。
ユニオンと型エイリアス
type Status = "draft" | "published" | "archived";
function updateStatus(status: Status) {
if (status === "draft") {
console.log("編集可能です。");
} else if (status === "published") {
console.log("公開中です。");
}
}
updateStatus("draft");
// updateStatus("unknown"); // エラー
型エイリアス(type)を使うと,複雑な型定義を再利用しやすくなります。
Generics(ジェネリクス)
型の一部を引数として受け取れる仕組みです。
function createList<T>(items: T[]): T[] {
return [...items];
}
const numbers = createList([1, 2, 3]);
const names = createList(["前夜祭", "本祭"]);
ジェネリクスは React Hooks や API 呼び出しのラッパーなどで頻繁に登場します。
ハンズオン:スタッフ管理ユーティリティ
src/staff.tsを作成し,Staffインターフェースを定義。- メンバーを追加・削除・検索する関数を実装します。
interface Staff {
id: number;
name: string;
role: "system" | "design" | "publicity";
joinedAt: Date;
}
const database: Staff[] = [];
export function addStaff(staff: Staff) {
database.push(staff);
return database.length;
}
export function getStaffByRole(role: Staff["role"]) {
return database.filter((staff) => staff.role === role);
}
src/index.tsから利用します。
import { addStaff, getStaffByRole } from "./staff.js";
addStaff({
id: 1,
name: "田中 一郎",
role: "system",
joinedAt: new Date(),
});
console.log(getStaffByRole("system"));
npx tsc --watchを使うと保存時に自動で再コンパイルされます。
TypeScript + ESLint
Chapter 3 で導入した ESLint を TypeScript 対応にするには,追加のパッケージが必要です。
.eslintrc.json の例:
{
"parser": "@typescript-eslint/parser",
"parserOptions": { "ecmaVersion": "latest", "sourceType": "module" },
"plugins": ["@typescript-eslint"],
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
"ignorePatterns": ["dist"]
}
練習課題
Staffにskills: string[]を追加し,スキルで検索できる関数を実装。- API から取得したデータ(Chapter 4)に TypeScript の型を付けてみましょう。レスポンスの構造を
typeで表現します。 readonly修飾子を使い,変更してはいけないプロパティを保護してみましょう。
次のステップ
TypeScript の基礎を押さえたら,React / Next.js の章でコンポーネント開発に挑戦しましょう。
ここまでのコードは GitHub に push し,学習の記録として残しておくと役立ちます。