Generate Typed Code from JSON — TypeScript, Python, Go, Rust & More

Convert JSON to typed code in 8 programming languages. See how type inference works, with before-and-after examples for TypeScript interfaces, Python dataclasses, Go structs, Rust serde, and more.

JSONTech チームMarch 25, 202611 min

なぜJSONからコードを生成するのか?

JSON APIを利用するプロジェクトは、最終的に型付きモデルが必要になります。サンプルレスポンスをエディタにコピーし、フィールドを目視で確認し、インターフェースや構造体を手動で書き始めます。これは機能しますが、ペイロードに40フィールド、3階層のネスト、ポリモーフィックオブジェクトの配列が含まれると、面倒でエラーが発生しやすく、遅くなります。

コードジェネレーターは、その手動ステップを排除します。JSONサンプルを貼り付け、言語を選択し、数秒で本番用の型定義を取得します。その利点は具体的です:

  • 時間の節約 — 50フィールドのペイロードの型を生成するのに数秒で済みます。
  • 型安全性 — コンパイラやランタイムが、本番環境に到達する前に不一致をキャッチします。
  • ボイラープレートの削減 — ゲッター、セッター、JSONタグ、またはserdeアノテーションを手書きする必要がなくなります。
  • 一貫性 — チームの全メンバーが同じソースデータから同じモデルを取得します。

型推論の仕組み

JSONからコードへのジェネレーターは、サンプルデータを読み取り、各値の型を推論します。文字列はstringになり、数値は小数点の有無に応じてintまたはfloatになり、ブール値は直接マッピングされ、nullはオプショナル/ヌラブルラッパーを生成します。オブジェクトは名前付き型(構造体、クラス、インターフェース)になり、配列はその要素の型付きコレクションになります。

以下は、JSON型が言語間でどのようにマッピングされるかです:

JSONタイプTypeScriptPythonJavaGoRustSwift
文字列stringstrStringstringStringString
数値(int)numberintintint64i64Int
数値(float)numberfloatdoublefloat64f64Double
ブール値booleanboolbooleanboolboolBool
nullnullNonenull*T (ポインタ)Option<T>T?
オブジェクトinterfacedataclassclass (POJO)structstructstruct (Codable)
配列T[]list[T]List<T>[]TVec<T>[T]

重要な洞察:ジェネレーターは見たものしか知りません。サンプルデータに42が含まれていて、そのフィールドが42.5にもなり得る場合、ジェネレーターはfloatではなくintを選択します。正確な型のためには、代表的なサンプルデータを使用してください。

サンプル入力

以下の例で使用するJSONです。文字列、数値、ブール値、ネストされたオブジェクト、配列をカバーしています:

{
  "id": 1,
  "name": "アリス・ジョンソン",
  "email": "alice@example.com",
  "active": true,
  "score": 97.5,
  "address": {
    "street": "123 メインストリート",
    "city": "ポートランド",
    "zip": "97201"
  },
  "tags": ["admin", "editor"]
}

JSONからのTypeScriptインターフェース

TypeScriptは最も一般的なターゲットです。ジェネレーターは各オブジェクトのインターフェースを作成し、フィールド名をプロパティキーとして使用します:

interface Address {
  street: string;
  city: string;
  zip: string;
}

interface Root {
  id: number;
  name: string;
  email: string;
  active: boolean;
  score: number;
  address: Address;
  tags: string[];
}

すべてのフィールドに型が付けられ、ネストされたaddressオブジェクトは独自のインターフェースを取得し、tagsはその内容からstring[]として推論されます。これをプロジェクトに直接貼り付けて、完全なオートコンプリートとコンパイル時チェックを使用して開始できます。

JSONからのPythonデータクラス

Pythonの@dataclassデコレーターは、__init____repr__、および比較メソッドを自動的に生成します。型ヒントと組み合わせることで、PythonでJSONモデルを定義する最もクリーンな方法です:

from dataclasses import dataclass

@dataclass
class Address:
    street: str
    city: str
    zip: str

@dataclass
class Root:
    id: int
    name: str
    email: str
    active: bool
    score: float
    address: Address
    tags: list[str]

これをdacitecattrsのようなライブラリと組み合わせて、JSON辞書をこれらのデータクラスインスタンスに直接デシリアライズできます。

JSONからのJava POJO

Javaはより多くの儀式を必要とします — フィールド、コンストラクタ、ゲッター/セッター。ジェネレーターはここで最も多くの時間を節約します:

public class Address {
    private String street;
    private String city;
    private String zip;

    public String getStreet() { return street; }
    public void setStreet(String street) { this.street = street; }
    public String getCity() { return city; }
    public void setCity(String city) { this.city = city; }
    public String getZip() { return zip; }
    public void setZip(String zip) { this.zip = zip; }
}

public class Root {
    private int id;
    private String name;
    private String email;
    private boolean active;
    private double score;
    private Address address;
    private List<String> tags;

    // ゲッターとセッター...
}

生成されたPOJOは、Jackson、Gson、またはJavaエコシステム内の他のJSONシリアル化ライブラリと直接動作します。

JSONからのGo構造体

Goの構造体は、フィールドタグを使用してJSONマーシャリングを制御します。ジェネレーターは、エクスポートされたフィールドとjson:"..."タグを持つ慣用的なGoを生成します:

type Address struct {
    Street string `json:"street"`
    City   string `json:"city"`
    Zip    string `json:"zip"`
}

type Root struct {
    ID      int64    `json:"id"`
    Name    string   `json:"name"`
    Email   string   `json:"email"`
    Active  bool     `json:"active"`
    Score   float64  `json:"score"`
    Address Address  `json:"address"`
    Tags    []string `json:"tags"`
}

タグは、json.Unmarshalが小文字のJSONキーをエクスポートされた(大文字の)Goフィールドにマッピングすることを保証します。フィールド名は自動的にパスカルケースになり、idはGoの命名規則に従ってIDになります。

JSONからのRust構造体

Rustはシリアル化のためにserdeクレートを使用します。ジェネレーターは必要なderiveマクロを追加します:

use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
pub struct Address {
    pub street: String,
    pub city: String,
    pub zip: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Root {
    pub id: i64,
    pub name: String,
    pub email: String,
    pub active: bool,
    pub score: f64,
    pub address: Address,
    pub tags: Vec<String>,
}

serde_jsonを使用すると、JSON文字列をこれらの構造体にデシリアライズするためにserde_json::from_strを1回呼び出すだけで済みます。コンパイラはすべてのフィールドが存在し、正しく型付けされていることを強制します。

JSONからのSwift Codable

SwiftのCodableプロトコルは、外部依存関係なしでJSONのエンコードとデコードを可能にします:

struct Address: Codable {
    let street: String
    let city: String
    let zip: String
}

struct Root: Codable {
    let id: Int
    let name: String
    let email: String
    let active: Bool
    let score: Double
    let address: Address
    let tags: [String]
}

JSONDecoder().decode(Root.self, from: data)を使用して、JSONデータをこれらの構造体に直接解析します。Swiftはプロパティ名からコーディングキーを自動的に推論します。

ネストされたオブジェクトと配列の処理

ネストされたオブジェクトは、コード生成の最も興味深い部分です。ジェネレーターが別のオブジェクト内にオブジェクト値を見つけると、別の名前付き型を作成します。命名規則は通常、フィールド名に基づいています:

  • オブジェクトを含むaddressという名前のフィールドは、Addressという型を生成します。
  • shipping_detailsという名前のフィールドはShippingDetailsを生成します(パスカルケース)。
  • 深くネストされたオブジェクトは、同じパターンを再帰的に追います — ネストされたcoordinatesオブジェクトを持つaddressは、AddressCoordinatesの両方の型を生成します。

オブジェクトの配列も同様に処理されます。itemsがオブジェクトの配列である場合、ジェネレーターは最初の要素を調べ(またはすべての要素をマージし)、型を推論し、Itemのような単数名の型を作成します。

プリミティブの配列(["admin", "editor"])は簡単です — それらはターゲット言語に応じてstring[]Vec<String>[]stringなどになります。

より良い生成コードのためのヒント

生成された型の品質は、入力データの品質に完全に依存します。いくつかの実用的なヒント:

  • 代表的なサンプルデータを使用する。 各フィールドのバリエーションの少なくとも1つの例を含めます。フィールドがnullになり得る場合、生成器がオプショナルとしてマークできるように、null値を含めてください。
  • 型を一貫させる。 idが一部のレコードでは数値で、他では文字列の場合、生成器は1つを選択するか、ユニオン型を使用する必要があります。サンプルデータを最初にクリーンアップしてください。
  • ルート型の名前を変更する。 ほとんどのジェネレーターは、最上位の名前としてRootをデフォルトにします。生成後にUserApiResponseのような意味のある名前に変更してください。
  • 生成前にフラット化する 必要な構造のサブセットだけが必要な場合。JSONサンプルを関心のあるフィールドだけにトリムします。
  • エッジケースを確認する。 空の配列([])はコンテキストなしでは型付けできません。生成器がアイテムの型を知るために、少なくとも1つの要素でそれらを埋めてください。
  • レビューして調整する。 生成されたコードは出発点です。フィールドの名前を変更したり、整数の幅を調整したり、バリデーションアノテーションを追加したり、ドメイン知識に基づいてオプショナルフィールドをマークしたりすることがあるかもしれません。

自分で試してみる

型付きコードを瞬時に生成する: 任意のJSONを私たちのJSON to Codeジェネレーターに貼り付けて、TypeScript、Python、Java、Go、Rust、Swift、Kotlin、C#の本番用型を取得してください。サインアップは不要です。

関連ツール