JSON から TypeScript への推論の仕組み
推論はパースされた JSON ツリーに対する 1 回のパスです。ツールは各値を読み取り、TypeScript の型を選択し、見つけたオブジェクトごとに 1 つのインターフェースを書き出します。
- ブラウザーのネイティブパーサーで JSON サンプルをパースし、不正な入力を行・列のヒントとともに拒否します。
- 各値の TypeScript 型を推測します——
string、number、boolean、null、配列、またはネストされたオブジェクト。 - すべてのネストされたオブジェクトに親プロパティキーから派生したインターフェース名を付けます(例:
user.addressはAddressインターフェースになります)。 - 各配列にわたってアイテム型をマージし、
{id: 1}と{id: 2, label: "x"}のリストが正しいオプショナルフィールドを持つユニオンを生成するようにします。 - オプション(interface vs type、readonly、オプショナル nullable)を適用し、前方参照なしにファイルがコンパイルされるよう依存関係順に宣言を出力します。
JSON から TypeScript の型を生成する理由
- ほとんどの形状バグは、レスポンス型が記述されていればコンパイル時に検出できます。実際のペイロードからインターフェースを推論することで大部分が自動生成され、`strict` モードがドキュメントに記載されていなかったフィールドを検出します。
- 推論されたインターフェースを Zod や io-ts などのランタイムバリデーターと組み合わせると、同じ形状に 2 つの役割を与えられます:開発時のエディターオートコンプリートと、本番環境が予期しないものを送ってきたときのエッジでの 400 エラー。
- TypeScript の言語サーバーは知っているフィールドしか表示しません。推論されたインターフェースをインポートすれば、ドットを入力した瞬間にオートコンプリートが機能します——レスポンスへの `as any` キャストとリポジトリ全体の grep が不要になります。
- OpenAPI 仕様を書こうとしているなら、推論されたインターフェースはレスポンススキーマの素早い最初のドラフトです。手書きの例や制約はまだ必要ですが、プロパティ名と型はすでに正確です。
主な用途
推論は実際のペイロードが存在してもスキーマがない場合に最も役立ちます。
- Stripe、GitHub、Twilio からのサードパーティ Webhook ペイロードの型付け(ハンドラーを書く前に)。
- フロントエンドチームがバックエンドと同日にコーディングを開始できるように、社内 REST API のための型のブートストラップ。
- 観測された API レスポンスから Zod、io-ts、または Valibot スキーマの出発点を生成。
出力はどのようなものですか?
JSON サンプルドキュメントとルート名を指定すると、ジェネレーターはネストされたオブジェクトごとに 1 つずつインターフェースのツリーを生成します。以下の入力とルート名 User の場合:
{"id":1,"name":"Alice","tags":["a","b"],"address":{"city":"Paris"}} をルート名 User で貼り付けると、ジェネレーターは以下を生成します:
export interface User {
id: number;
name: string;
tags: string[];
address: Address;
}
export interface Address {
city: string;
}
address が独自の名前付きインターフェースに昇格されていることに注目してください——これが依存関係順の出力です。同じ JSON で type 宣言スタイルを選択すると export type User = {...} が出力されます;readonly トグルをオンにすると、すべてのプロパティに readonly 修飾子が付きます。
ジェネレーターオプション
宣言スタイル
interface(オブジェクト形状の標準的な TypeScript イディオム)または type(後でマップ型、条件型、インターセクションが必要な場合に便利)を選択します。どちらも同一のランタイム動作を生成します;選択はコーディングスタイルの好みです。
オプショナルな null 許容フィールド
サンプル値が null の場合、フィールドの型は T | null になります。このオプションをオンにすると、API がキー全体を省略して null を返さない場合に便利なように、フィールドが TypeScript 側でオプショナルになるよう ? 修飾子も追加されます。
readonly 修飾子
すべてのプロパティ宣言の前に readonly を追加し、出力されるインターフェースが不変のデータモデルと一致するようにします。Redux の状態スライス、フリーズされた API レスポンス、またはコンパイラーに偶発的な変更をフラグさせたい場所に便利です。
ネストされたオブジェクトと配列に対応していますか?
はい。すべてのネストされたオブジェクトは親プロパティキーから派生した名前付きインターフェースになり、配列はその内容からアイテム型を推論します。オブジェクトの配列はオブジェクトの形状ごとにインターフェースを取得し、形状が一致しない場合はユニオン型になります。
オプショナルフィールドはどのように推論されますか?
「null 許容フィールドをオプショナルとしてマーク」トグルをオンにすると、サンプル値が null のフィールドはキーに ? 修飾子と型に | null が付きます。トグルなしではフィールドは必須のままで、型は単に T | null です。
判別共用体に対応していますか?
基本的なユニオン型は、配列に形状の異なるアイテムが含まれる場合や、フィールドが値と null の両方を持つ場合に生成されます。完全な判別共用体の推論(type や kind をタグとして選択してバリアントを分割する)には複数のサンプルが必要です——これは計画中ですが現在のビルドには含まれていません。
複数の JSON サンプルから型を推論できますか?
まだできません——現在の推論器は一度に 1 つのサンプルを読み込みます。1 つのインターフェースを共有すべき 2 つのペイロード(例:リストエンドポイントと単一アイテムエンドポイント)がある場合の実用的な回避策は、それらを 1 つの配列にマージして生成し、結果のユニオン型を改名することです。マルチサンプル推論はロードマップにあります——これがあるレスポンスには存在し別のレスポンスには存在しないフィールドを検出する唯一の方法だからです。
ペイロードを貼り付け、ルートに名前を付け、インターフェースをコピーしてください。パイプライン全体がブラウザーで動作するため、未リリースの API や署名済み Webhook 本文があなたのマシンに残ります。