kind 判別可能ユニオン

最終更新:2026-10-22

kind 判別可能ユニオン

判別可能ユニオン(tagged union とも呼ばれます)は、共通の判別フィールド(status、kind など)で一連の型を結び付け、各メンバーの判別フィールドに互いに異なるリテラル値を取らせます。判別フィールドを switch すると、TS が自動的に対応するメンバーへナローイングます。業務モデリングで最も実用的なユニオン型の使い方です。

グループナローイングとアサーション
種類型
strict モード不要

ℹ️ 説明 エディタは TypeScript を JavaScript にトランスパイルして実行します(型チェックなし)。型チェック結果は各サンプルの出力を参照してください。

📝 構文

type Result<T> =
  | { status: "loading" }
  | { status: "success"; data: T }
  | { status: "error"; message: string };

function handle<T>(res: Result<T>) {
  switch (res.status) {
    case "loading": /* res: data なし */ break;
    case "success": res.data; break;   // success メンバーにナローイング
    case "error":   res.message; break;
  }
}

⚙️ パラメータ

discriminant判別フィールド。各メンバーが必ずこのフィールドを持ち、値は互いに異なるリテラル型("loading" / "success" / "error" など)でなければなりません

戻り値:戻り値はありません。判別可能ユニオンは型レベルのモデリング手段であり、switch/if による判別フィールドの比較をきっかけに、コンパイル時にナローイングが行われます。

▶ サンプル

下のコードを編集して「試す」を押すと、トランスパイル実行結果を確認できます:

出力:

loading…
got 3 items
error: timeout

(トランスパイル後の実行出力。success 分岐で res.data が型チェックを通るのは、判別フィールドによるナローイングのおかげです。tsc が静的に保証し、実行時に見えるのは値だけです)

💡 ポイント

ℹ️ 説明 判別フィールドの名前に制限はなく、type、kind、status、state、tag がよく使われます。重要なのはメンバーごとに異なるリテラル値を取ることで、TS が一意に識別できるようにすることです。
⚠️ 注意 判別フィールドは必須のリテラル型でなければなりません。"success" のようなリテラルではなく string と書いたり、オプショナルにしたりすると識別力が失われ、ナローイングが効かなくなります。
💡 ヒント 判別可能ユニオンと網羅性チェックは黄金の組み合わせです。すべての判別値を switch しておけば、メンバーを追加したときにコンパイラが漏れた分岐をすべて指摘します(assertNever と併用。exhaustive-checks の項目を参照)。
ケースは今後追加予定です。

📚 関連チュートリアル

❓ よくある質問

Q 判別可能ユニオンと普通のユニオン型の違いは何ですか?
A 普通のユニオンは typeof/in のような汎用チェックでしか絞り込めません。判別可能ユニオンはリテラルの判別フィールドを持つため、1つのフィールドを switch するだけで正確に1つのメンバーへ到達でき、網羅性チェックも可能です。判別フィールドを設計できるなら優先して使いましょう。
Q 判別フィールドはオブジェクトの内側にネストできますか?
A できます。TS はネストしたプロパティ(配列の要素でさえも)に対する判別ナローイングをサポートします。たとえば res.meta.state のように。ただしネストが深いほど可読性が落ちるため、慣例では判別フィールドはトップレベルに置きます。
Q 数値列挙を判別値として使えますか?
A 使えます。列挙メンバー(数値列挙を含む)はリテラル型なので、メンバーごとに異なる列挙値を取れば判別可能ユニオンになります。デバッグ時の読みやすさは文字列列挙の方が数値列挙に勝ります。
Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%