JSON→TypeScript変換

JSONを貼り付けて、TypeScriptインターフェースを瞬時に取得します。

データはデバイスを離れません

使い方

  1. JSONを左側のパネルに貼り付けます(オブジェクトまたは配列)。
  2. 変換をクリック · TypeScriptインターフェースが右側に表示されます。
  3. 必要に応じてルート名を調整し、オプションを有効にします。
  4. 出力をコピーをクリックして、生成されたコードをコピーします。

よくある質問

ネストされたオブジェクトを処理しますか?

はい。各ネストされたオブジェクトには独自の名前付きインターフェースが付与されます。配列要素も型を決定するために分析されます。

混在型の配列はどうなりますか?

配列に異なる型の要素が含まれる場合、コンバーターはユニオン型(例: string | number)を使用します。

ルートでJSON配列をサポートしますか?

はい。ルート値が配列の場合、コンバーターはその要素を分析し、適切なインターフェースと配列の型エイリアスを生成します。

コンバーターが実際に行うこと

JSONを解析し、すべての値を走査して、形状を記述するTypeScriptの interface 宣言のセットを出力する。ネストされたオブジェクトはそれぞれ独自の名前付きinterfaceを得る。PascalCaseで親プロパティキーから導出され(user フィールドは User interfaceになる)。2つのネストされたオブジェクトが名前で衝突すると、2番目に数値サフィックスが付く(UserUser2)。ルートでは、配列は type Root = RootItem[]; エイリアスと RootItem interfaceになり;オブジェクトは単一の Root interface(または「root name」フィールドに入力した名前)になる。

サンプルの入力と出力:

// Input
{
  "id": 42,
  "name": "Ada",
  "active": true,
  "tags": ["admin", "billing"],
  "profile": { "bio": "Programmer", "link": null }
}

// Output
export interface Root {
  id: number;
  name: string;
  active: boolean;
  tags: string[];
  profile: Profile;
}

export interface Profile {
  bio: string;
  link: unknown;
}

JSON → TypeScript 型マッピング

JSON値生成されたTS
"hello"string
42 または 3.14number(TSには別の整数型がない)
true / falseboolean
nullunknown(コンバーターはフィールドがnullableなのか、このサンプルで欠落しているだけなのかを判断できない)
[]unknown[]
[1, 2, 3]number[]
[1, "x"](number | string)[]
{ "a": 1 }名前付き interface

ルートレベルのオブジェクト配列の場合、コンバーターはすべてのアイテムのキーを1つの代表的なinterfaceにマージする。アイテムが同じ形状を共有している場合は適切な近似だが、形状が本当に異なる場合(例:異種のevents配列)は情報が失われる。その場合は生成後に判別共用体を手動で記述する必要がある。

オブジェクトに interface、ルート配列に type が使われる理由

公式TypeScript Handbookは一行のヒューリスティックを示している:「interface を使え。type の機能が必要になったときだけ切り替えよ。」どちらも構造的型付けで、どちらもオブジェクトの形状を記述できる。しかし interface はオブジェクト形状に有利だ。宣言マージ(interfaceを再開いてフィールドを追加)をサポートし、extends でクリーンに機能し、コンパイラエラーに名前で表示される。type エイリアスはプリミティブの共用体、複数型の交差、または非オブジェクトに名前をつける必要がある場合に必要となる。そのためルートレベルの配列はinterfaceではなく type Root = RootItem[]; エイリアスを使う。

命名について:コンバーターはレガシーの I プレフィックスなしのPascalCaseを使う(User であって IUser ではない)。最新のTSスタイルガイド(Google、Microsoft、Reactコミュニティ)はほぼ普遍的にプレフィックスを廃止している。プロパティ名はJSONキーと完全に一致する(JSONがcamelCaseならcamelCase、snake_caseならsnake_case)。有効なJS識別子でないキー(ハイフン、スペースを含む、または数字で始まる)は引用符で囲まれる:"foo-bar": string;

このツールができないこと(限界を正直に)

単一のJSONの例は実際のスキーマより情報が少ないため、検出できれば望ましいいくつかのことが入力だけでは不可能だ:

このツールを使う場面

コードファースト vs スキーマファースト vs ダイレクト(このツールの位置付け)

ランタイムデータからTypeScript型を取得する3つの一般的なワークフロー:

適切な選択は、主に静的型チェックが関心事か(このツールが最適)、それともランタイム安全性も必要か(Zod / Effect Schemaを使う)によって異なる。

よくある間違い

  1. 生成された型を完成した仕様として扱う。これらは70%完成した出発点だ。オプションフィールドには ?、本当にnullableな箇所には | null、該当する場所には文字列リテラル共用体を追加する。
  2. APIにバリアントがある場合に単一の例から生成する。email が時々存在して時々しないuserオブジェクトは「emailは必須」として生成される。複数の例でコンバーターを実行して結果を共用体にするか、手動で編集する。
  3. すべてを readonly として自動的にマークする。不変のデータフローには有用だが、変更するステートオブジェクトには誤りだ。readonly トグルは慎重に使う。
  4. 大きな整数IDの精度を信頼する。JavaScriptの number は253−1が上限だ。64ビットIDには文字列として転送し、string として型定義する。
  5. interfacetype を混同する。異なるツール、異なるトレードオフ。TypeScript Handbookのヒューリスティックは「typeが提供する機能が必要になるまではinterfaceを使え」で、まさにこのツールが行っていることだ。
  6. 機密JSONをサーバーサイドコンバーターに貼り付ける。実際のAPIレスポンスには顧客データ、認証情報、内部IDが含まれることが多い。ブラウザのみの変換(このツール)はデータをマシン上に保持する。

よくある質問

フィールドがすべて必須としてマークされた理由は?

単一のJSONの例ではどのフィールドが実際のAPIで時々省略されるかをコンバーターに伝えられないからだ。例に現れるすべてのキーが必須になる。フィールドがオプションとわかっている場合は手動で末尾に ? を追加する:email?: string;。複数サンプルのオプション性検出には、より高機能な quicktype CLIがネイティブに対応している。

nullフィールドが unknown と型付けされる理由は?

単一のnullからコンバーターはフィールドが常にnullable(string | null)なのか、このサンプルでたまたまnullだっただけ(string)かを判断できないからだ。unknown が保守的なデフォルトで;TypeScriptは値を使う前に型を絞り込むことを強制する。これは any より安全だ。APIの意図がわかったら string | null に手動で編集する。

interfacetype どちらを使うべきですか?

公式TypeScript Handbookのヒューリスティック:interface を使い、主に共用体型、交差型、またはプリミティブに名前をつけるなど type のみが提供する機能が必要なときだけ切り替える。このコンバーターはそのルールに従う:すべてのオブジェクト形状には interface、ルート配列エイリアスには type。一部のスタイルガイドはデフォルトで type を使うことを推奨しているが(Matt Pocockが公に主張している)、慣例的なデフォルトはオブジェクトにはinterfaceだ。

JSONはどこかにアップロードされますか?

いいえ。変換は JSON.parse でJSONを解析し、値を走査してTypeScriptの出力をtextareaに書き込む自己完結型のJavaScript IIFEだ。fetchも、JSONコンテンツを運ぶアナリティクス呼び出しも、サーバーも存在しない。実際のAPIレスポンスには顧客データ、内部ID、認証情報が含まれることが多く、第三者を経由させたくないため、これは重要だ。

JSDoc、Zod、またはランタイム検証はどうですか?

このツールはコンパイル時のTypeScript型のみを出力する:ランタイムバリデーターなし(Zod / Yup / Effect Schemaなし)、JSDocコメントなし。ランタイム検証と静的型の両方が必要な場合は、Zodでスキーマを記述して z.infer<typeof Schema> で型を導出する。JSON SchemaがありランタイムとTS型の両方が必要なら、json-schema-to-typescript + AJVが慣例的なペアリングだ。

interfaceの名前に I プレフィックスがない理由は?

最新のTypeScriptスタイルガイドのほとんどがそれを廃止しているからだ。GoogleのTypeScript Style Guideは明示的に推奨しない;Reactコミュニティはプレフィックスなしのパスカルケースに収束している。レガシーの IUser 規約は初期TypeScriptへのC# / Javaの影響から来ており、現在の慣行はシンプルな User だ。

関連ツール

無料の JSON フォーマッタ&バリデータ・オンライン 無料JSON→Go構造体コンバーター JSONスキーマジェネレーター