JSON から TypeScript
JSON のサンプルから TypeScript の interface を生成します。
このツールについて
JSON レスポンスを貼り付けると、対応する TypeScript の interface が得られます。ネストしたオブジェクトはそれぞれ名前付きの interface になり、オブジェクトの配列はマージされて省略可能なフィールドに ? が付き、型が混在する値はユニオン型になります。
使い方
- API から返された JSON レスポンスのサンプルを貼り付けます。
- ルートの型の名前を設定します。例: User、OrderResponse。
- interface か type の宣言か、また export するかどうかを選びます。
- 生成された TypeScript をプロジェクトにコピーし、サンプルからはわからなかった部分を調整します。
よくある質問
- 省略可能なフィールドはどう判定されますか?
- 配列に複数のオブジェクトが含まれている場合、一部のオブジェクトにないフィールドは省略可能として ? が付きます。単一のオブジェクトからは省略可能なフィールドがわからないため、できれば複数の要素を含むサンプルを使ってください。
- フィールドが null 型になるのはなぜですか?
- サンプルで null だったため、実際の型がわからないからです。API が返す内容がわかったら、string | null などに置き換えてください。
- interface と type、どちらを使うべきですか?
- どちらも JSON の記述に使えます。interface は拡張やマージができ、エラーメッセージが少しわかりやすくなります。ユニオン型には type エイリアスが必要です。コードベースで既に使っている方を選んでください。
- 実行時にデータを検証しますか?
- いいえ。TypeScript の型はコンパイル時に消えます。実行時にデータを検証するには、これらの型と一緒に Zod などのスキーマライブラリを使ってください。
- JSON のルートが配列の場合はどうなりますか?
- ルートは配列の型エイリアスになります。ルートの名前が User で、サンプルが [{"id": 1}] なら、type User = UserItem[] と、要素用の UserItem インターフェースが得られます。ルートを Users のように複数形で命名すれば、代わりに type Users = User[] が得られます。
- 厳密な JSON ではなく JavaScript のオブジェクトを貼り付けられますか?
- はい。シングルクォート、クォートのないキー、末尾のカンマ、Python の True、False、None は型を生成する前に JSON に変換されるため、Node の console.log や Python シェルからコピーした出力も使えます。関数やクラスのインスタンスなど、JSON で表現できない値はエラーになります。
- 配列の要素の型が DataItem という名前になるのはなぜですか?
- 要素の型は、配列のキーを単数形にして命名されます。users からは User、entries からは Entry になります。data や children のようにキーに複数形の語尾がない場合は、代わりに Item が付加され、DataItem や ChildrenItem になります。別の名前がよければ、貼り付けた後にエディターで名前を変更してください。
JSON から TypeScript のインターフェースを生成する方法
実際の API レスポンスを貼り付けると、すべての JSON オブジェクトが名前付きの TypeScript インターフェースになります。フィールド名はそのまま使われ、値は string、number、boolean に対応付けられます。入れ子のオブジェクトにはキーにちなんだ名前の宣言が個別に作られるため、address フィールドからは Address インターフェースが生成されます。オブジェクトの配列は単数形で命名され、orders からは Order[]、categories からは Category[] が得られます。「ルートの名前」には、User のようにコードで使う型名を設定してください。
生成された TypeScript はそのままコンパイルできるので、types.ts ファイルに貼り付けるか、ダウンロードしてください。"first-name" や "2fa" のように識別子として無効なキーはクォートで囲まれます。2 つの入れ子のオブジェクトが同じ名前になる場合は、2 つ目に Address2 のように番号が付きます。空の配列は unknown[]、空のオブジェクトは Record<string, unknown> になります。サンプルからはその中身が何もわからないためです。
JSON からユニオン型が推論される仕組み
同じフィールドに異なる種類の値が入る場合、その型はユニオン型になります。[1, "two", null] のような配列は (string | number | null)[] と型付けされ、ある項目では文字列、別の項目では数値になるフィールドは string | number になります。同じ配列内のオブジェクトは、形のユニオンではなく 1 つのインターフェースにマージされ、一部のオブジェクトにしかないフィールドはオプショナルになります。
マージはレコードのリストには適していますが、タグ付きユニオンが見えなくなります。events 配列に {"type": "click", "x": 3} と {"type": "key", "code": "Enter"} が混在していると、type が string で、x と code の両方がオプショナルな Event インターフェースが 1 つ生成されます。type: "click" のものと type: "key" のものの 2 つのインターフェースからなる判別可能なユニオン型に手で書き直せば、TypeScript が type フィールドで型を絞り込めるようになります。
JSON から TypeScript: サンプルから生成するか、スキーマから生成するか
JSON のサンプルが示すのは 1 つのレスポンスであって、契約ではありません。実際には日付である文字列、"active" | "banned" のような列挙値、2^53 を超えるかもしれない数値 ID、ときどきしか現れないフィールドは、1 つの例からは見えません。生成されたインターフェースはたたき台として扱い、配列の項目を複数含むレスポンスを貼り付けたうえで、status: string を許可される値のユニオンに置き換えるなど、わかっている部分の型を厳しくしてください。
API が OpenAPI ドキュメントや JSON Schema を公開している場合は、そちらから型を生成してください。サーバーが返しうるすべてのフィールドが記述されているためです。JSON から型を生成するのは、仕様のないサードパーティの API、Webhook のペイロード、古い社内エンドポイントのための手早い方法です。自分で管理していないデータには、Zod スキーマなど同じ形のランタイムチェックを追加すれば、レスポンスが変わったときに見過ごされず、はっきりとエラーになります。
うまく動かない、または結果がおかしいですか? このツールの問題を報告