TypeScriptのenumとその代替手段
ホーム
TypeScriptのenum
TypeScriptのenum:数値、文字列、constと代替手段 | We.Inc
自分のメンバー名から数値enum、文字列enum、const enumを生成し、それぞれが出力するJavaScriptを正確に確認して、as constオブジェクトやリテラルのユニオン型と比較します。
enumは、名前付き定数の集合に1つの型を与えます。数値enumは0から順に数え、数値から名前への逆引きもできます。文字列enumはメンバーごとにリテラルが必要で、逆引きはありません。const enumはインライン化されて消えます。TypeScriptの大半の機能と違い、通常のenumは実際のJavaScriptを出力するため、多くのチームはas constオブジェクトを好みます。
固定された値の集合を表す5つの方法
スタイル JavaScriptを出力するか 逆引き 生のリテラルを受け付けるか
数値enum する、オブジェクト あり、数値から名前 メンバーに一致する数値
文字列enum する、オブジェクト なし 不可、Enum.Memberを使う必要がある
const enum しない、値がインライン化 なし 元のenumの種類に従う
as constオブジェクト する、普通のオブジェクト なし(必要なら自分で書く) 可
生成ツールにメンバー名を入力し、スタイルを切り替えてみてください。TypeScriptの宣言と、コンパイラーが出力するJavaScriptを書き出すので、それぞれの選択のコストをバンドルに入る前に確認できます。
メンバー名をカンマ区切りで入力します。例:Draft, Review, Live。 数値enumの場合は開始番号を設定します。以降のメンバーはそこから順に数えられます。 スタイルを選ぶと、その宣言、出力されるJavaScript、使い方が表示されます。 プロジェクトに合うものをコピーします。
APIのフィールドやデータベースのカラムなど、プログラムの外に出る値には文字列enumかas constオブジェクトを選びましょう。ログに2と出るより、liveと出るほうが読みやすくなります。 どこかに保存される数値enumでは、メンバーの並べ替えや途中への挿入を絶対にしないでください。以降の番号がすべてずれ、保存済みの古いデータが別の意味になってしまいます。 公開ライブラリではconst enumを避けましょう。isolatedModulesや型ストリッパーでコンパイルする利用側は、別ファイルの値をインライン化できません。 Nodeの型ストリッピングで.tsファイルを実行するなら、erasableSyntaxOnlyを有効にしましょう。実行時に失敗する前にenumを検出してくれます。
よくある質問
逆引き(リバースマッピング)とは何ですか?
数値enumの場合、tscはオブジェクトに両方向を保存するので、Direction.Upは0、Direction[0]は文字列のUpになります。文字列メンバーには逆引きのエントリーがありません。値が他のメンバーの名前と衝突する可能性があるためです。
文字列enumを受け取る関数に普通の文字列を渡せないのはなぜですか?
文字列enumのメンバーはそれぞれ別個の型です。コンパイラーはリテラルをenumに代入できないと報告するため、呼び出し側はStatus.Draftと書く必要があります。呼び出し側にリテラルを渡させたい場合は、代わりに文字列リテラルのユニオン型を使いましょう。
enumの値をループで処理するには?
文字列enumなら、Object.values(MyEnum)が値を返します。数値enumではオブジェクトに逆引きのキーも含まれるので、絞り込みます:Object.values(MyEnum).filter((v) => typeof v === 'number')。
enumは非推奨ですか?
いいえ。enumは引き続きTypeScriptの一部です。TypeScript 5.8で追加された新しいerasableSyntaxOnlyオプションは、型ストリッピングに依存するプロジェクトがenumを禁止できるようにするだけです。enumは型注釈を削除するだけでは取り除けないからです。
Node.jsはenumを含むファイルを直接実行できますか?
デフォルトの型ストリッピングではできません。Nodeのドキュメントでは、enum宣言はコード生成が必要でこのモードではサポートされない機能として挙げられています。tscや他のトランスフォーマーでコンパイルするか、as constオブジェクトに切り替えましょう。
数値enum:コンパクトだが壊れやすい
初期値がなければ、メンバーには順に0、1、2と番号が振られます。最初のメンバーにLow = 1のように値を与えると、残りはそこから続きます。出力されるオブジェクトには、名前から数値と数値から名前の両方が含まれます。 そのコンパクトさはリスクでもあります。番号はコードの外では何の意味も持たず、途中にメンバーを追加すると、それ以降のすべてが黙って番号を振り直されます。
文字列enum:読みやすく厳格
すべてのメンバーに文字列リテラルが必要なので、ログ、URL、JSONの中で値がそれ自体で意味を持ちます。厳格さには両面があります。APIから読み込んだ値はenumではなく文字列なので、enumとして扱う前にチェックが必要です。
as constパターン
as constを付けたオブジェクトリテラルは、正確な文字列値を型として保持します。type Role = (typeof Role)[keyof typeof Role]と組み合わせると、反復処理用の実行時オブジェクトと、Role.Adminとリテラルのadminの両方を受け付けるユニオン型が手に入ります。 これは型注釈付きの普通のJavaScriptなので、どの型ストリッパーでも処理でき、書いたオブジェクト以外に余計なものは生成されません。
3種類のenumとその出力
開始値付きの数値enum
MidとHighはLowから続けて数えられます。出力オブジェクトは両方向に対応します。
文字列enum
各メンバーは一度だけ代入され、逆引きのエントリーはありません。
const enum
宣言は消え、使用箇所はそれぞれ値に置き換わります。
消去可能な代替手段
as constオブジェクトと派生ユニオン型
型ストリッパーで動作し、Object.valuesで反復でき、生の文字列も受け付けます。
実行時のリストが不要なら普通のユニオン型
完全に消去されますが、コンパイラーはそれ以外の文字列を引き続き拒否します。
型ストリッピングを使うプロジェクトでenumを禁止
このオプションを付けると、enum宣言はコンパイルエラーになります。
数値enum
文字列enum
const enum
as constオブジェクト
ユニオン型
enum生成ツール
型名
メンバー(カンマ区切り)
最初の番号
enumのスタイル
TypeScript
出力されるJavaScript
TypeScriptをコピー
JavaScriptをコピー
名前は英字、$、_のいずれかで始め、英字、数字、$、_のみを含め、同じ名前を二度使わないでください。
{n}個のメンバー
無料で始める · クレジットカード不要
関連: ガイド|Webマーケティングと集客を学ぶ
製品
ご利用いただける方
機能
リソース
会社情報
サイトマップを見る