カテゴリ: TypeScript 更新日: 2025/12/15

TypeScriptの型ガード・ユニオン型・リテラル型まとめ!型安全な実装の基本を徹底解説

TypeScriptの型ガード・ユニオン型・リテラル型まとめ!型安全な実装の基本
TypeScriptの型ガード・ユニオン型・リテラル型まとめ!型安全な実装の基本

先生と生徒の会話形式で理解しよう

生徒

「TypeScriptでデータの種類ごとに処理を変えることってできますか?」

先生

「もちろんできます。TypeScriptではユニオン型リテラル型、そして型ガードを使って、安全に判定できます。」

生徒

「型ガードって何ですか?想像がつきません。」

先生

「型ガードとは、データがどの型なのかを見分けるための仕組みです。実際の例を見ながら理解してみましょう。」

1. ユニオン型とは?

1. ユニオン型とは?
1. ユニオン型とは?

TypeScriptのユニオン型は、ひとつの変数に複数の型を持たせられる機能です。ユニオンは英語で「まとめる」「一つにする」という意味で、例えば、numberstringの両方を扱いたいときに役立ちます。

プログラミング未経験の方は、ユニオン型を「入れ物に入る荷物の種類が複数ある状態」と考えると理解しやすいと思います。箱に本か洋服のどちらかを入れるように、変数に数字か文字のどちらかを入れることができます。


let value: number | string;
value = 100;
value = "こんにちは";

2. リテラル型とは?

2. リテラル型とは?
2. リテラル型とは?

リテラル型とは、値を特定の決められたものだけに限定する型です。例えば、「赤」「青」「黄色」の三つの言葉だけを許可したい場合に使います。ゲームで「初級」「中級」「上級」の三つの難易度しか選べないようにするイメージです。


let level: "初級" | "中級" | "上級";
level = "中級"; // OK
// level = "神級"; // エラー

3. 型ガードとは?

3. 型ガードとは?
3. 型ガードとは?

型ガードとは、実行中に「今の値はどの型か?」を判定して、適切な処理へ導く仕組みです。ユニオン型だけでは、変数の中身が数字か文字か判断できず、そのまま計算や文字操作ができません。

そこで、型ガードを使って型を判定すれば、エラーを避けて安全に処理できます。


function print(value: number | string) {
    if (typeof value === "string") {
        console.log(value.toUpperCase());
    } else {
        console.log(value * 2);
    }
}
print("apple"); // APPLE
print(10);       // 20

4. 独自の型ガード(自作型ガード関数)

4. 独自の型ガード(自作型ガード関数)
4. 独自の型ガード(自作型ガード関数)

TypeScriptでは、isキーワードを使って独自の型ガード関数を作れます。複雑なオブジェクトやAPIレスポンスの判定に便利です。


type Dog = { type: "dog", bark: () => void };
type Cat = { type: "cat", meow: () => void };

function isDog(animal: Dog | Cat): animal is Dog {
    return animal.type === "dog";
}

function call(animal: Dog | Cat) {
    if (isDog(animal)) {
        animal.bark();
    } else {
        animal.meow();
    }
}

5. 型ガード・ユニオン型・リテラル型の使いどころ

5. 型ガード・ユニオン型・リテラル型の使いどころ
5. 型ガード・ユニオン型・リテラル型の使いどころ

TypeScriptで型の安全性を高めると、予期せぬエラーを防ぎ、安心して開発できます。特に以下の場面で役に立ちます。

  • 入力フォームなどでユーザーの入力がどの型か分からないとき
  • APIレスポンスが複数パターンあるとき
  • ゲームや画面状態の表示切替を管理するとき

type Screen = "loading" | "success" | "error";

function show(screen: Screen) {
    if (screen === "loading") console.log("読み込み中です…");
    if (screen === "success") console.log("成功しました!");
    if (screen === "error") console.log("エラーが発生しました");
}

このように、ユニオン型とリテラル型で表示できる状態を制限し、型ガードで正しい処理を実行すれば、安全でバグの少ないコードを書けるようになります。

まとめ

まとめ
まとめ

TypeScriptにおける型安全な設計の重要性

ここまで、TypeScriptのユニオン型リテラル型、そして型ガードについて順番に学んできました。これらはすべて、TypeScriptが持つ「型安全」という大きな特徴を支える重要な仕組みです。JavaScriptでは実行してみないと分からなかったエラーも、TypeScriptを使えば事前に気づくことができます。その中でも、複数の型を扱う場面で特に力を発揮するのがユニオン型と型ガードです。

ユニオン型を使うことで、「この変数には数値か文字列のどちらかが入る」といった柔軟な設計が可能になります。一方で、柔軟さだけでは安全とは言えません。そこでリテラル型を組み合わせることで、許可された値だけに制限し、意図しない値が入るのを防ぎます。さらに型ガードを使えば、実行時に正しい型を判定し、その型に応じた安全な処理を書くことができます。

ユニオン型とリテラル型を組み合わせた設計

実際の開発現場では、ユニオン型とリテラル型は単独で使われるよりも、組み合わせて使われることがほとんどです。例えば、画面の状態管理や処理の分岐、APIレスポンスの判定など、状態が限定されているケースではリテラル型が非常に有効です。これにより、「想定外の状態」がコードに入り込む余地を減らすことができます。


type Status = "idle" | "loading" | "success" | "error";

function changeStatus(status: Status) {
    if (status === "idle") {
        console.log("待機中です");
    } else if (status === "loading") {
        console.log("処理を実行しています");
    } else if (status === "success") {
        console.log("処理が完了しました");
    } else {
        console.log("問題が発生しました");
    }
}

このような書き方をすることで、状態管理が明確になり、後からコードを読む人にも意図が伝わりやすくなります。TypeScriptの型定義は、ドキュメントの役割も果たすため、チーム開発でも大きなメリットがあります。

型ガードで実現する安全な分岐処理

型ガードは、ユニオン型とセットで考えることが大切です。ユニオン型だけでは「どの型か分からない状態」が残りますが、型ガードを使えばその不安を解消できます。typeof演算子やin演算子、独自に作成した型ガード関数など、用途に応じて使い分けることが重要です。


type Result =
    | { kind: "success"; message: string }
    | { kind: "error"; errorCode: number };

function handleResult(result: Result) {
    if (result.kind === "success") {
        console.log(result.message);
    } else {
        console.log("エラーコード:", result.errorCode);
    }
}

この例では、リテラル型であるkindの値を判定することで、TypeScriptが自動的に型を絞り込み、安全にプロパティへアクセスできるようになります。この仕組みを理解すると、複雑な条件分岐も安心して書けるようになります。

学習のポイントと実務への活かし方

初心者の方は、まず「ユニオン型で複数の型を扱える」という点を理解し、その次に「リテラル型で値を限定できる」という考え方を身につけるとよいでしょう。そして最後に、型ガードによって安全に分岐処理を書く流れを意識すると、TypeScriptらしいコードが自然に書けるようになります。

小さなサンプルでも構わないので、実際に手を動かしながら試すことが大切です。型エラーが出たときに「なぜこのエラーが出ているのか」を考えることが、理解を深める近道になります。

先生と生徒の振り返り会話

生徒

「ユニオン型って、最初は難しそうに感じましたけど、複数の型をまとめて扱える便利な仕組みなんですね。」

先生

「そうですね。ただし、まとめただけでは安全とは言えないので、型ガードでしっかり判定することが大切です。」

生徒

「リテラル型を使うと、値の候補を限定できるのも分かりました。状態管理に向いていそうですね。」

先生

「その通りです。リテラル型と型ガードを組み合わせると、読みやすくてバグの少ないコードになります。」

生徒

「TypeScriptはエラーが多くて大変だと思っていましたけど、実は守ってくれる存在なんですね。」

先生

「まさにその理解が大切です。型を味方につけることで、安心して開発できるようになりますよ。」

関連記事:
カテゴリの一覧へ
新着記事
New1
TypeScript
TypeScriptでパスエイリアスを設定する方法!baseUrlとpathsでコードをスッキリ整理
New2
JavaScript
JavaScriptのfor文の書き方を初心者向けにやさしく解説
New3
JavaScript
JavaScriptの関数でよくあるエラーとその解決法まとめ
New4
JavaScript
JavaScriptのイベント処理でよくあるエラーとその対処法
人気記事
No.1
Java&Spring記事人気No1
JavaScript
JavaScriptのインストール方法まとめ!Windows・Mac・Linux別にステップ解説
No.2
Java&Spring記事人気No2
JavaScript
JavaScriptのマウスイベントの使い方(click, mouseoverなど)
No.3
Java&Spring記事人気No3
JavaScript
JavaScriptのtoStringとString関数の違いを初心者向けに解説
No.4
Java&Spring記事人気No4
JavaScript
JavaScriptの純粋関数(pure function)と副作用の違いを理解しよう
No.5
Java&Spring記事人気No5
JavaScript
JavaScriptプログラムの実行方法まとめ!ブラウザ・Node.js・コンソールの使い方
No.6
Java&Spring記事人気No6
TypeScript
TypeScript学習におすすめの無料教材・リファレンスサイト【初心者向け】
No.7
Java&Spring記事人気No7
JavaScript
JavaScriptで文字列をforループで1文字ずつ処理する方法!初心者向け解説
No.8
Java&Spring記事人気No8
JavaScript
JavaScriptのDOMContentLoadedとloadイベントの違いを理解しよう