はじめに
TypeScript の enum は一見便利そうですが、いくつかの理由から非推奨または「できるだけ使わないほうがよい」とされることがあります。以下、その理由を解説します。
1. JavaScriptにコンパイルすると余計なコードが生成される
TypeScript の enum は JavaScript にコンパイルされる際に、意図しないオブジェクトが生成されるため、コードサイズが増えたり、パフォーマンスが低下する可能性があります。
例: TypeScriptのenum
enum Color {
Red,
Green,
Blue,
}
コンパイル後のJavaScript
"use strict";
var Color;
(function (Color) {
Color[Color["Red"] = 0] = "Red";
Color[Color["Green"] = 1] = "Green";
Color[Color["Blue"] = 2] = "Blue";
})(Color || (Color = {}));
console.log(Color.Red); // 0
console.log(Color[0]); // "Red"(双方向マッピング)
このように、enum は 双方向マッピング(数値→文字列、文字列→数値の両方の変換)を持つオブジェクトに展開されます。この動作は enum の可読性を上げるためですが、コードサイズが増え、意図しない挙動の原因にもなります。
2. JavaScriptの標準機能と相性が悪い
TypeScript の enum は JavaScript の標準仕様には存在しないため、普通のオブジェクトや const で定義された値と比べて扱いにくい ことがあります。
特に Object.keys(Color)
のような標準的なオブジェクト操作をすると、enum の双方向マッピングのため余計な値が取得される可能性があります。
3. const enum の制限
パフォーマンスを考慮して const enum を使うこともできますが、一部の環境では動かないため注意が必要です。
const enum の使い方
const enum Color {
Red,
Green,
Blue,
}
コンパイル後のJavaScript
console.log(0); // 直接数値に置き換えられる
この方法ならば JavaScript に余計なオブジェクトが生成されず、最適化されます。しかし、Babel などのトランスパイラでは const enum がサポートされないことがあるため、使用できない場合があります。
4. 可読性と型安全性の問題
TypeScript の enum は、型安全性が低い ケースがあります。
例えば、enum の値はどんな数値でもセットできてしまうため、想定外の値が代入される可能性があります。
例: enumに不正な値を代入
enum Status {
Active = 1,
Inactive = 2,
}
let userStatus: Status = Status.Active;
userStatus = 3; // ❌ エラーにならない(意図しない値がセットできる)
これは enum が 型安全ではない ことを示しています。
5. 推奨される代替手段
最近のTypeScriptでは enum の代わりに、as const
を使ったオブジェクト型 または Union Type(ユニオン型) を推奨するケースが増えています。
(1) as const
を使ったオブジェクト型
const Color = {
Red: "Red",
Green: "Green",
Blue: "Blue",
} as const;
type Color = typeof Color[keyof typeof Color];
let myColor: Color = Color.Red; // ✅ 型安全
// myColor = "Yellow"; // ❌ エラー
メリット
- enum のような使い勝手
- 型安全
- 余計な JavaScript コードを生成しない
(2) ユニオン型を使う
type Color = "Red" | "Green" | "Blue";
let myColor: Color = "Red"; // ✅ 型安全
// myColor = "Yellow"; // ❌ エラー
メリット
- enum よりシンプルで型安全
- JavaScriptに余計なコードを生成しない
結論
enum が推奨されない理由
- 余計なJavaScriptコードが生成され、コードサイズが増える
- JavaScriptの標準的なオブジェクトと異なる動作をする
-
const enum
には環境依存の制約がある - 型安全ではない(不正な値をセットできる)
-
as const
や ユニオン型 の方がシンプルで型安全
新しいTypeScriptのプロジェクトでは、enum を使わずに as const
や ユニオン型 を使うことが一般的になっています。