オライリーの『プログラミングTypeScript』を読んでいるのですが、その中でenum
とconst enum
の違いが述べられています。
内容が気になったので、実際にプログラムを書いて実験してみました。
実験内容
サンプルコード
次のサンプルコードを作成しました。
これをnpx tsc index.ts
でコンパイルし、JavaScriptを出力します。
// enum enum Ab { C = 1, D = "Two" } console.log("This is enum", Ab.C) console.log("This is enum", Ab.D) // const enum const enum Ef { G = 3, H = "Four" } console.log("This is const enum", Ef.G) console.log("This is const enum", Ef.H)
コンパイル結果
次の内容が実際のコンパイル結果として出力されたJavaScriptです。 なかなかに示唆的であることがわかります。
// enum var Ab; (function (Ab) { Ab[Ab["C"] = 1] = "C"; Ab["D"] = "Two"; })(Ab || (Ab = {})); console.log("This is enum", Ab.C); console.log("This is enum", Ab.D); console.log("This is const enum", 3 /* G */); console.log("This is const enum", "Four" /* H */);
実験結果からわかったこと
enumは即席関数経由でオブジェクトが生成される
コンパイル後のJavasScriptから、通常のenumは即席関数を経由して、オブジェクトが生成されることがわかりました。
また、enumの値を数値(1)にしたケースと文字列(Two)にしたケースの違いも、示唆に富んでおりおもしろいです。
TSにおけるC = 1
が、JSではAb[Ab["C"] = 1] = "C";
となり、カッコ内で代入が実現しています。
/* Before(TypeScript) */ enum Ab { C = 1, D = "Two" } console.log("This is enum", Ab.C) console.log("This is enum", Ab.D)
/* After(JavasScript) */ var Ab; (function (Ab) { Ab[Ab["C"] = 1] = "C"; Ab["D"] = "Two"; })(Ab || (Ab = {})); console.log("This is enum", Ab.C); console.log("This is enum", Ab.D);
const enumはインライン展開される
次にconst enum
ですが、これはインライン展開された結果、跡形もなく消え去っていることがわかります。
これは私の推測ですが、const enum
は不変の存在なので、わざわざオブジェクトに展開する必要がないということだと思います。
/* Before(TypeScript) */ const enum Ef { G = 3, H = "Four" } console.log("This is const enum", Ef.G) console.log("This is const enum", Ef.H)
/* After(JavasScript) */ console.log("This is const enum", 3 /* G */); console.log("This is const enum", "Four" /* H */);
ちなみに余談ですが、// enum
はコメントも含めてコンパイル結果に残っていたのですが、// const enum
はコメントも一緒に消失していました。
tscのコンパイラーが、TypeScript内のコメントをどのように扱うのか、地味に気になります。
TypeScriptのenumは、そもそも使用するべきではない
なお『プログラミングTypeScript』では、そもそもenumを安全に使用するのは難しいとも書かれています。 何故かという理由は書くと長くなりそうですが、enumについて言及されている記事がいくつかありますので、参考としてご紹介します。
まとめ
tsc
のコンパイル結果から、enum
とconst enum
の違いを理解しました。
そもそもenumを使うべきではないと言ったら元も子もないですが、示唆的な違いを垣間見ることができ、おもしろかったです。
またtsc
のコンパイラーは、一般的なコンパイラーと異なり生成結果がJavasScriptなので、生成結果にも一定の可読性があります。
私たちがプログラミングしたTypeScriptが、実際にどのようなJavasScriptに変換されるのか、見比べてみるとおもしろいかもしれません。
プログラミングTypeScript ―スケールするJavaScriptアプリケーション開発
- 作者:Boris Cherny
- 発売日: 2020/03/16
- メディア: 単行本(ソフトカバー)