繰り返しJSON値からTypeScript Enumを生成する

繰り返し出現するカテゴリ値を含むJSONフィールドからTypeScript enumを生成する方法を学びます。enumと文字列リテラルユニオンの比較も解説。

Type Refinements

詳細な説明

JSONデータからのEnum生成

JSONフィールドが少数のカテゴリ値を含む場合、ランタイム表現とリバースマッピング機能を持つTypeScriptのenumを文字列リテラルユニオンよりも好む場合があります。

JSON例

[
  { "name": "Bug Report", "priority": "high" },
  { "name": "Feature Request", "priority": "medium" },
  { "name": "Documentation", "priority": "low" }
]

生成されるTypeScript(enumスタイル)

enum Priority {
  High = "high",
  Medium = "medium",
  Low = "low",
}

interface Ticket {
  name: string;
  priority: Priority;
}

Enum vs 文字列リテラルユニオン

特徴 Enum 文字列リテラルユニオン
ランタイム値 あり(オブジェクトにコンパイル) なし(コンパイル時に消去)
リバースマッピング あり(数値enumの場合) なし
Tree-shaking 部分的 完全
ランタイムで反復可能 あり(Object.values なし
プレーンJS互換 コンパイルが必要 そのまま動作

Enumを選択すべき場合

  • すべての可能な値をランタイムで反復する必要がある場合(例:ドロップダウンの構築)。
  • enumを型と値の両方の位置でインポートしたい場合。
  • コードベースの規約が既にenumを使用している場合。

ユニオンを好むべき場合

  • 最小限のバンドルサイズを求める場合(ユニオンはTypeScriptによって消去される)。
  • as constアサーションで同様の動作を実現している場合。
  • プレーンJavaScriptファイルとの互換性が必要な場合。

Const Enum

const enum Priority {
  High = "high",
  Medium = "medium",
  Low = "low",
}

const enumはコンパイル時に完全にインライン化され、ランタイムオブジェクトは出力されません。ただし、--isolatedModules(Babel、SWC、esbuildで使用)と互換性がないため、ほとんどの現代的なプロジェクトでは避けられています。

ユースケース

チケット管理システムを構築し、優先度の値をドロップダウンのレンダリングやフィルタチップの表示のために、型としてもランタイム値としても利用する必要がある場合に使用します。

試してみる — JSON to TypeScript

フルツールを開く