ユニオン型 |
| 対応: | TypeScript 1.0(2014) |
|---|
「AまたはB」という複数の型のいずれかを受け付ける型です。『|』(パイプ)で複数の型をつなげて表現し、TypeScriptがどちらの型かを自動で絞り込む「ナローイング」と組み合わせて使います。
構文
// ユニオン型の定義
let 変数名: 型1 | 型2 = 値;
// 型エイリアスとして定義
type 型名 = 型1 | 型2 | 型3;
// 判別ユニオン: 共通のリテラル型プロパティで型を識別します。
type 型名 =
| { kind: "A"; プロパティ: 型 }
| { kind: "B"; プロパティ: 型 };
構文一覧
| 構文 | 概要 |
|---|---|
| 型1 | 型2 | ユニオン型です。型1または型2のいずれかを受け付けます。 |
| typeof 変数 === "型名" | ナローイングの一手段です。typeofでプリミティブ型を絞り込みます。 |
| instanceof | ナローイングの一手段です。クラスのインスタンスかどうかで型を絞り込みます。 |
| in 演算子 | ナローイングの一手段です。オブジェクトに特定のプロパティが存在するかで型を絞り込みます。 |
| 判別ユニオン | 共通のリテラル型プロパティ(タグ)を使って型を識別する設計パターンです。 |
サンプルコード
// 基本的なユニオン型
let value: string | number = "文字列";
value = 42; // 数値も代入できます。
// ナローイング: typeofで型を絞り込みます。
function printValue(val: string | number): void {
if (typeof val === "string") {
// このブロック内ではvalはstring型として扱われます。
console.log(val.toUpperCase()); // 文字列のメソッドが使えます。
} else {
// このブロック内ではvalはnumber型として扱われます。
console.log(val.toFixed(2)); // 数値のメソッドが使えます。
}
}
printValue("hello"); // 『HELLO』と出力されます。
printValue(3.14159); // 『3.14』と出力されます。
// null許容型: string | nullで未設定を表現します。
function greet(name: string | null): string {
if (name === null) {
return "ゲストさん、こんにちは";
}
return `${name}さん、こんにちは`;
}
console.log(greet(null)); // 『ゲストさん、こんにちは』と出力されます。
console.log(greet("桐生一馬")); // 『桐生一馬さん、こんにちは』と出力されます。
// 判別ユニオン: kindプロパティで型を識別します。
type Circle = { kind: "circle"; radius: number };
type Square = { kind: "square"; side: number };
type Shape = Circle | Square;
function getArea(shape: Shape): number {
switch (shape.kind) {
case "circle":
// ここではshapeはCircle型として扱われます。
return Math.PI * shape.radius ** 2;
case "square":
// ここではshapeはSquare型として扱われます。
return shape.side ** 2;
}
}
console.log(getArea({ kind: "circle", radius: 5 }).toFixed(2)); // 『78.54』と出力されます。
console.log(getArea({ kind: "square", side: 4 })); // 16と出力されます。
実行すると次のように出力されます。
npx ts-node ts_union.ts HELLO 3.14 ゲストさん、こんにちは 桐生一馬さん、こんにちは 78.54 16
概要
ユニオン型は『|』で複数の型を組み合わせた「どちらかの型」を表す型です。JavaScriptでは関数が文字列も数値も受け取れるケースが多いですが、TypeScriptのユニオン型を使うことで、その意図を型として明示できます。
ユニオン型の変数を使うとき、TypeScriptはどの型かが確定するまで、共通するメソッド・プロパティしか使わせません。『if』や『switch』で型を絞り込む(ナローイング)ことで、絞り込み後のブロック内では具体的な型のメソッドが使えるようになります。
判別ユニオンは、すべての型に共通のリテラル型プロパティ(タグ)を持たせることで、switch文での型絞り込みを安全に行えるパターンです。neverを使った網羅チェックと組み合わせると、新しい型の追加漏れをコンパイル時に検出できます。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。