【TypeScript】Enum型の概要と扱いにくい理由について

TypeScript
この記事は約5分で読めます。

Enum型とは

Enum型とは列挙型と呼ばれ,いくつかの値を一つにまとめて宣言することができるもの.
ここでの値とは,number型, string型, boolean型などの型をもつ値である.

またEnum型で宣言された値をenumと呼ぶこととする(正式には違うかもしれない)

例として以下のようなコードを書いてみた

enum CardSuit {
    Clubs,
    Diamonds,
    Hearts,
    Spades
}

const cardNum = CardSuit.Clubs
console.log(cardNum)
// 出力: 0

const card = CardSuit[0]
console.log(card)
// 出力: "Clubs"

CardSuitは「Clubs,Diamonds,Hearts,Spades」という値をもつenumである.
ここで宣言した4つの値は,ドット( . )や角括弧( [ ] )とで呼び出すことができる.

またenumで宣言した値はデフォルトだと全てnumber型で定義(0,1,2,…)されているため,CardSuit.Clubsのように呼び出すと0の値が返ってくる.ちなみにClubsという値そのものを呼び出したい場合は,ClubsはCardSuitの先頭要素なのでCardSuit[0]と書けば良い.

個人的には,デフォルトだと全てnumber型というのは少しわかりにくいので,基本的にenumを利用する場合は以下のように明示的に宣言することが好ましい.

enum CardSuit {
    Clubs=0,
    Diamonds=1,
    Hearts=2,
    Spades=3
}

上記のように,enumで宣言したそれぞれの値が全てnumber型のものを,ドキュメント(ページ下,参考に記載)では数値列挙型と読んでいる.
また今回はデフォルトと同様に0,1,2,3を割り当てているが,他の数字を割り当てるor先頭要素のみを割り当てることも可能である.

例えば,以下のように先頭要素のClubsに10を割り当てただけの場合,

enum CardSuit {
    Clubs=10,
    Diamonds,
    Hearts,
    Spades
}

Diamonds,Hearts,Spadesには11,12,13が割り当てられる

またnumber型だけではなく,以下のようにstring型を扱うことも可能である.

enum CardSuitStr{
    Clubs="クラブ",
    Diamonds="ダイアモンド",
    Hearts="ハート",
    Spades="スペード"
}

上記の場合はstring型を値として保持しているので,文字列列挙型と呼んでいる.

このようにenum型では,いくつかの値を事前に一つにまとめて宣言して扱うことができる

Enum型は扱いにくい?

よく「Enum型は扱いにくい」という話を耳にするので,その理由について挙げてみる.

これはなぜかというと,「他のやり方の方がわかりやすい」からである.
例えば,「ある値しか代入したくない!」というケースを考える.
今回の場合,cardという変数にはClubs,Diamonds,Hearts,Spadesという文字列しか代入したくないとした場合,Enum型を使って以下のように書くことができる.

enum CardSuit {
    Clubs,
    Diamonds,
    Hearts,
    Spades
}

const card = CardSuit[0]
console.log(card)
// 出力: "Clubs"

ただEnum型を用いた場合のデメリットとして,「文字列が直接代入できない」という点がある.
そのためこういうケースでは,以下のようにリテラル型で型宣言することが多い.

type CardSuit = "Clubs" | Diamonds | Hearts | Spades;

const card = "Clubs"

また別のケースとして「値の参照」を考える.

気づいたと思うが,さきほど挙げた文字列列挙型では,形がほとんど辞書型と同じなのである.
値の参照方法についてもCardSuitStr.Clubs(== “クラブ”)のように辞書型と同様であり,これなら辞書型を使えばいいのでは,という話である.

またアプリケーション開発においても,APIレスポンスが辞書型の値(json形式)で受け取るケースが多いのではないだろうか.そのため使い慣れている,という観点でもわざわざEnum型を使う必要はない,というのが自分としての意見である.

結論

今回色々調べてみた結果,TypeScriptではEnum型よりもtypeやinterfaceを用いて型宣言した値を用いて開発した方が良いのでは,と思った.

ただこれは自分が実践経験がまだまだ短いというのもあって,もしかすると今後Enum型を使った方が良いケースというのも出てくるかもしれないので,その時はまた勉強し直そうと思う.

参考

Enum - TypeScript Deep Dive 日本語版
TypeScriptのenumを使わないほうがいい理由を、Tree-shakingの観点で紹介します
2022-LINE-engineering-site

コメント

タイトルとURLをコピーしました