実践LESSON 07
この教材で学ぶこと 型・union・narrowing・runtime validationで変更を安全にします。TypeScript入門
対象読者: JavaScriptの基本を理解し、規模が大きくても変更しやすいコードを書きたい人。
この教材でできるようになること
- TypeScriptが実行前に行う型検査の役割を説明できる
- object、union、narrowingを使って状態を表せる
unknownを安全に検証できる- compiler optionの
strictが重要な理由を説明できる
1. TypeScriptはJavaScriptへ型検査を加える
TypeScriptの型は、実行前に不整合を発見するための情報です。ブラウザやNode.jsで動く時点では通常JavaScriptへ変換されています。
function formatProgress(done: number, total: number): string {
if (total <= 0) throw new Error("total must be positive");
return `${done}/${total}`;
}
formatProgress("3", 5); // 型エラー
2. objectの形を定義する
type Lesson = {
id: string;
title: string;
level: "beginner" | "intermediate" | "advanced";
completed: boolean;
};
function nextLesson(lessons: Lesson[]): Lesson | undefined {
return lessons.find((lesson) => !lesson.completed);
}
文字列を何でも許可せずunionで候補を限定すると、表記揺れを型検査で防げます。
3. discriminated unionで状態を表す
type LoadState =
| { status: "idle" }
| { status: "loading" }
| { status: "success"; lessons: Lesson[] }
| { status: "error"; message: string };
function message(state: LoadState): string {
switch (state.status) {
case "idle": return "待機中";
case "loading": return "読み込み中";
case "success": return `${state.lessons.length}件`;
case "error": return state.message;
}
}
statusを確認すると、TypeScriptはそのbranchで利用可能なpropertyを絞り込みます。
4. 外部入力はunknownから始める
API responseやJSONは、型注釈を書くだけでは実行時に検証されません。
function isLesson(value: unknown): value is Lesson {
if (typeof value !== "object" || value === null) return false;
const candidate = value as Record<string, unknown>;
return typeof candidate.id === "string"
&& typeof candidate.title === "string"
&& typeof candidate.completed === "boolean"
&& ["beginner", "intermediate", "advanced"].includes(String(candidate.level));
}
型の外側にある入力境界では、runtime validationが必要です。
5. anyを避ける
anyはその値に対する型検査を事実上止めます。分からない値にはunknownを使い、調べてから操作します。
function errorMessage(error: unknown): string {
return error instanceof Error ? error.message : "Unknown error";
}
6. strictから始める
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true
}
}
既存の大規模JavaScriptへ段階導入する事情がなければ、最初からstrictを有効にするほうが安全です。
演習: API responseを検証する
次のJSONをunknownとして受け取り、Lesson[]であることを検証する関数を作ってください。
[
{ "id": "ts-01", "title": "TypeScript入門", "level": "beginner", "completed": false }
]
配列か、全要素がisLessonを満たすかを確認し、不正なら理由を含む例外を投げます。
理解チェック
- compile-timeの型とruntimeの値を区別できる
- unionとnarrowingで状態を表現できる
-
unknownを検証してから利用できる -
anyが型安全性を失わせる理由を説明できる
公式資料
次に読む
テストとデバッグで、型検査だけでは保証できない振る舞いを確かめます。