enumは使わずにas const等でreadonlyのconstを作成することについて
TypeScriptのEnumについて
enumとは
enumは、関連する定数のグループを一緒に束ねるための機能。たとえば、以下のようにenumを使用することで、特定の集合の値(この場合は方角)を表すことができる。
enum Direction { Up, Down, Left, Right }
enumはいくつかの問題点を抱えている。例えば、生成されるJavaScriptが予想外の挙動を示すことがあったり、enum内の値が実行時に変更可能であるなどの問題がある。
生成されるJavaScriptが想定外の挙動を示す:
enum Colors { Red, Green, Blue }
上記がJSにコンパイルされると
var Colors; (function (Colors) { Colors[Colors["Red"] = 0] = "Red"; Colors[Colors["Green"] = 1] = "Green"; Colors[Colors["Blue"] = 2] = "Blue"; })(Colors || (Colors = {}));
生成されたコードはパフォーマンス上の理由から問題となることもある。
実行時にenumの値が変更可能である:
TypeScriptのenumは実行時にJavaScriptオブジェクトとして存在する。これは、enumの値がランタイムで変更可能であることを意味する。
enum Colors { Red, Green, Blue } Colors.Red = 10; // これが可能。
これはenumがconstであるべきであるという考え方とは対照的。
これらの問題を避けるためには、TypeScriptのas const構文を使用して、readonlyなオブジェクトを作成する方法が推奨される。
as const構文を使用してreadonlyな定数を作成する
これは"const assertions"と呼ばれ、TypeScript 3.4以降で利用可能。
const Directions = { Up: "UP", Down: "DOWN", Left: "LEFT", Right: "RIGHT" } as const;
この場合、Directionsは変更不可能(readonly)であり、そのプロパティはそれぞれ文字列リテラル型("UP"、"DOWN"、"LEFT"、"RIGHT")を持つ。これにより、enumと同じように関連する定数をまとめることができ、さらにenumの持つ問題を避けることが可能になる。