TypeScript 列挙型

列挙型、略してenumは、名前付きの値のセットを定義する方法の一つです。これらの値は、曜日やカードの並びのように、決まった選択肢を表す方法として使われます。

多くのプログラミング言語では、列挙型は特別なデータ型として実装されており、列挙型の各値には一意の整数値が割り当てられています。

デフォルトでは、enumの最初の値には値0が割り当てられ、それ以降の値はそれぞれ1ずつ増加します。しかし、enumの各メンバーに手動で値を割り当てることも可能です。

TypeScript enumの実装

それではトランプカードのスートを例に見てみましょう。

enum Suit {
    Club,
    Diamond,
    Heart,
    Spade
}

console.log(Suit.Club); // 0
console.log(Suit.Diamond); // 1

この例では、Suitという名前のenumを定義し、4つのメンバを定義しています。クラブ、ダイアモンド、ハート、スペードです。デフォルトでは、Clubには値0、Diamondには値1が割り当てられ、以下同様になります。

また、以下のようにenumの各メンバーに手動で値を割り当てることも可能です。

enum Suit {
    Club = 1,
    Diamond = 2,
    Heart = 4,
    Spade = 8
}

この例では、Suitの各メンバにそれぞれ1,2,4,8という値が割り当てられています。

TypeScript enumとswitch文の組み合わせ

enumの一般的な使用例は、switch文の中です。

enum Suit {
    Club = 1,
    Diamond = 2,
    Heart = 4,
    Spade = 8
}

let myCard: number = Suit.Club;

switch (myCard) {
    case Suit.Club:
        console.log("Club");
        break;
    case Suit.Diamond:
        console.log("Diamond");
        break;
    case Suit.Heart:
        console.log("Heart");
        break;
    case Suit.Spade:
        console.log("Spade");
        break;
} // "Club"

この例では、switch文がmyCardの値を使用して、実行するcaseを決定しています。case文では、Suitのメンバを使用してmyCardの値と照合しています。

TypeScript enumの逆マッピング

TypeScriptにおけるenumの機能の1つとして、逆マッピングと呼ばれるものがあります。

enum Suit {
    Club,
    Diamond,
    Heart,
    Spade
}

console.log(Suit[2]) // "Heart"

上記の例では、enum名(Suit)と値(2)を使って、値2の逆マッピングであるメンバ名Heartにアクセスしています。

対応する値が割り当てられていないインデックスを使ってenumメンバにアクセスしようとすると、undefinedが返されます。これは、TypeScriptのenumの逆マッピング機能が、単純に数値と対応する文字列名をマッピングするためで、そのマッピングが定義されていない場合はundefinedが返されることになる点に注意が必要です。

console.log(Suit[100]) // undefined

このような挙動を避けたい場合は、ユニオン型等を使用するのが良いかもしれません。ただ、完璧にenum型の挙動を再現できない点には注意が必要です。

const Suit = {
    Club: "Club",
    Diamond: "Diamond",
    Heart: "Heart",
    Spade: "Spade",
} as const

type Color = typeof Suit[keyof typeof Suit]; // type Suit = "Club" | "Diamond" | "Heart" | "Spade";

console.log(Suit.Club); // "Club"

このコードでは、4つのプロパティを持つSuitオブジェクトを定義しています。クラブ、ダイアモンド、ハート、スペードの4つのプロパティを持ち、それぞれがキー名の文字列値を持つSuitオブジェクトを定義しています。

as constアサーションは、Suitの値が単なる文字列としてではなく、リテラルな文字列値の集合として扱われることを保証するために使用されます。そして、Suitの型を抽出し、keyof演算子とtypeof演算子を用いてColorの型に代入しています。この結果、Color型は文字列リテラル値「Club」、「Diamond」、「Heart」、「Spade」の和集合として定義されることになります。

この記事を書いた人

著者の画像

Jeffry Alvarado

Ex-Facebook Engineer 大学ではコンピュータサイエンスを専攻し、在学中に複数のインターンシップを経験。コンピュータサイエンスが学習できるプラットフォームRecursionを創業し、CTOとしてカリキュラム作成、ソフトウェア開発を担当。


ツイート