0Pricing
TypeScript Academy · レッスン

判別可能なユニオンの構築

共通の判別プロパティでユニオンの各メンバーを識別します。

「判別可能なユニオンの構築」はCoddyKit上の無料TypeScript Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはTypeScript Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 TypeScript Academyコースには全4レッスンが含まれています。

判別可能なユニオンとは

判別可能なユニオンとは、判別子と呼ばれる共通のliteralプロパティを持つオブジェクト型のユニオンです。この共通のタグによって、TypeScriptは各メンバーを区別できます。

// The shared "kind" property is the discriminant
type Circle = { kind: "circle"; radius: number };
type Square = { kind: "square"; side: number };
type Shape = Circle | Square;

判別プロパティ

判別子は"circle"のようなリテラル型でなければならず、stringのような広い型ではいけません。各メンバーには、それぞれ固有のリテラル値を設定します。

type Circle = { kind: "circle"; radius: number };
type Square = { kind: "square"; side: number };

const c: Circle = { kind: "circle", radius: 10 };
console.log(c.kind); // "circle"

各メンバー固有のフィールド

共通の判別子に加えて、各メンバーはそのメンバーにだけ意味のあるフィールドを持ちます。円にはradiusがあり、正方形にはsideがあります。

type Circle = { kind: "circle"; radius: number };
type Square = { kind: "square"; side: number };
type Rectangle = { kind: "rectangle"; width: number; height: number };
type Shape = Circle | Square | Rectangle;

ユニオン値の構築

値を構築するとき、TypeScriptはその形状がkindに基づいてユニオンのちょうど1つのメンバーに一致するかをチェックします。

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number };

const shapes: Shape[] = [
  { kind: "circle", radius: 5 },
  { kind: "square", side: 4 }
];
console.log(shapes.length); // 2

単なるオプショナルフィールドではいけない理由

オプショナルフィールド(radius?、side?)を持つ緩い型では、無効な組み合わせを許してしまいます。判別可能なユニオンを使えば、不正な状態を表現できなくなります。

// Loose and error-prone: nothing stops radius + side together
type BadShape = { radius?: number; side?: number };
const bad: BadShape = { radius: 5, side: 4 }; // nonsense, but allowed

判別子の名前は自由に決められる

タグには慣例的にkindやtypeという名前を付けますが、すべてのメンバーが同じプロパティ名と異なるリテラル値を使う限り、どのような名前でも構いません。

type Event =
  | { type: "click"; x: number; y: number }
  | { type: "scroll"; delta: number };

const e: Event = { type: "click", x: 10, y: 20 };
console.log(e.type); // "click"

図形の面積計算機のモデル化

判別可能なユニオンは、各バリアントに異なる処理が必要な場合に特に力を発揮します。ここでは、後で面積関数が処理する図形を準備します。

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number };

const myShapes: Shape[] = [
  { kind: "circle", radius: 3 },
  { kind: "square", side: 6 }
];
console.log("Count:", myShapes.length);

3つ目のバリアントの追加

ユニオンは拡張できます。triangleメンバーの追加は1行の変更で済み、TypeScriptがユニオンを使っているすべての箇所でその追加を追跡します。

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number }
  | { kind: "triangle"; base: number; height: number };

const t: Shape = { kind: "triangle", base: 4, height: 8 };
console.log(t.kind);

固有のリテラルによる重複の防止

各kindが固有であるため、曖昧さはありません。値は必ず1つのメンバーにだけ該当し、同時に2つのメンバーになることはありません。

type A = { kind: "a"; value: number };
type B = { kind: "b"; label: string };
type Union = A | B;

function describe(u: Union) {
  return u.kind === "a" ? u.value : u.label;
}
console.log(describe({ kind: "b", label: "hi" }));

booleanタグを使う判別子

判別子は文字列である必要はありません。booleanリテラルも使えるため、成功・失敗の結果を表す場合に便利です。

type Result =
  | { ok: true; data: string }
  | { ok: false; error: string };

const r: Result = { ok: true, data: "loaded" };
console.log(r.ok ? r.data : r.error);

実践で使う判別可能なユニオン

これで完全な図形モデルができました。次のレッスンでは、判別子で絞り込みを行い、各メンバー固有のフィールドに安全にアクセスします。

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number };

const sample: Shape = { kind: "circle", radius: 7 };
console.log(sample.kind, "ready");

クイックチェック:判別子

判別可能なユニオンについての理解度を確認しましょう。

まとめ:判別可能なユニオンの構築

判別可能なユニオンでは、kindのようなリテラルの判別子を共有するオブジェクト型を組み合わせることを学びました。各メンバーは固有のフィールドを持ち、固有のリテラルによって重複を防ぎ、不正な状態を表現できないようにします。

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number };

const done: Shape = { kind: "square", side: 2 };
console.log("Recap complete:", done.kind);

よくある質問

「判別可能なユニオンの構築」レッスンは無料ですか?

はい。「判別可能なユニオンの構築」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、TypeScript Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 TypeScript Academyコースには全4レッスンが含まれています。

「判別可能なユニオンの構築」で何を学びますか?

共通の判別プロパティでユニオンの各メンバーを識別します。 ブラウザで直接実行するハンズオンコードでTypeScript Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

TypeScript Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのTypeScript Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。

「判別可能なユニオンの構築」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このTypeScript Academyレッスンでコードを書いて実行できますか?

はい。すべてのTypeScript Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 判別可能なユニオンの構築
  2. 判別プロパティによる型の絞り込み
  3. neverによる網羅性チェック
  4. ステートマシンのモデル化
← TypeScript Academyに戻る