JSONからTypeScriptへ:インターフェースと型の生成ガイド(2026)
JSONからTypeScriptへ最速で変換するには、ペイロードをJSON to TypeScript 変換ツールに貼り付け、生成されたインターフェースをコピーするだけでよい。インストールもアップロードも不要、ブラウザ内で完結する。「今すぐ型が欲しい」というケースはこれで片付く。
しかし、型を生成することと良い型を生成することは別物だ。変換ツールは推測するしかない。このフィールドはオプショナルなのか、それとも単に一つのサンプルから漏れているだけなのか。その配列は常に文字列なのか、ときには数値も混ざるのか。日付文字列はDateにすべきなのか。本ガイドで扱うのは、推論が実際にどう動くのか、interfaceとtypeをいつ使い分けるのか、そしてライブのAPIレスポンスを信頼できる型に変えるときに潜む本当の落とし穴だ。
JSONをTypeScriptに変換する方法
JSONからTypeScriptへの変換は3ステップで済む。
- JSONを貼り付ける。 オブジェクト、配列、または生のAPIレスポンスを入力ボックスに投入する。変換は完全にクライアントサイドで、瞬時に実行される。
- 出力を調整する。
interfaceかtypeを選び、UserやApiResponseといったルート名を設定し、exportキーワードを切り替え、オプショナルなフィールドには?:または| nullを選ぶ。 - コピーまたはダウンロードする。 生成されたTypeScriptをワンクリックで取得し、そのままコードベースに貼り付ける。
トランザクション的な経路はこれで完了だ。JSON to TypeScript 変換ツールは入力を読み取り、型ツリーを推論し、右側に定義を出力する。何一つページの外には出ない。本ガイドの残りは、ツールが推測できないケースを自分で修正できるよう、出力されたものを理解することがテーマだ。
JSONの型はTypeScriptにどう対応するか
すべてのJSON値にはTypeScriptの対応物がある。その対応はおおむね一対一だ。
| JSON値 | TypeScriptの型 |
|---|---|
"text" | string |
42、3.14 | number |
true / false | boolean |
null | null |
[1, 2, 3] | number[] |
{ ... } | interfaceまたはtype |
作業が発生するのはオブジェクトだ。典型的なRESTのユーザーペイロードを見てみよう。
{
"id": 101,
"name": "Ada Lovelace",
"email": "ada@example.com",
"active": true,
"roles": ["admin", "user"]
}
変換ツールはこのJSONから次のTypeScriptインターフェースを生成する。
export interface User {
id: number;
name: string;
email: string;
active: boolean;
roles: string[];
}
各スカラーはそれぞれのプリミティブ型に対応し、roles配列はstring[]になる。これをAPIクライアントに組み込めば、オートコンプリートとコンパイル時のチェックが無料で手に入る。
変換ツールはどう型を推論するか
推論アルゴリズムの中身を見ると、4つのルールで投げ込まれるもののほとんどはカバーできる。
構造的推論:オブジェクトごとに名前付きインターフェース1つ
それぞれ異なるオブジェクトの形が、独自の名前付きインターフェースになる。ネストされたオブジェクトはインライン型に潰されず、別個の参照される定義として引き上げられる。
{
"order": {
"id": "A-1",
"total": 42.5,
"customer": { "name": "Sam", "vip": false }
}
}
export interface Root {
order: Order;
}
export interface Order {
id: string;
total: number;
customer: Customer;
}
export interface Customer {
name: string;
vip: boolean;
}
同一の形は重複排除されるため、構造が同じ2つのフィールドはコピーを生成せず、単一のインターフェースを共有する。
配列のマージ:オプショナルなフィールドの推論
オブジェクトの配列を渡すと、変換ツールはそれらをキーごとにマージする。あるキーが一部の要素にあって他にはなければ、そのキーはオプショナルとして印が付く。
{
"users": [
{ "id": 1, "nick": "x" },
{ "id": 2 }
]
}
export interface Root {
users: User[];
}
export interface User {
id: number;
nick?: string;
}
idはすべての要素にあるので、必須のままだ。nickは2人目のユーザーにないため、nick?: stringになる。単一のサンプルではめったに十分でない理由がこれだ。後述の落とし穴の節を参照してほしい。
混在配列にはユニオン型
配列は同質である必要はない。要素が異なる型を持つとき、変換ツールはそれらを集めてユニオンにする。
{
"tags": ["a", "b"],
"meta": [1, "two"]
}
export interface Root {
tags: string[];
meta: (string | number)[];
}
tagsは一様に文字列なのでstring[]だ。metaは数値と文字列が混ざっており、(string | number)[]を生成する。空の配列はそもそも推論できず、unknown[]にフォールバックする。要素ゼロからは学べることが何もない以上、これは正直な結果だ。
オプショナルとnull:?:と| null
この2つは似て見えるが、意味は異なる。?:の印が付いたフィールドは、オブジェクトから完全に欠けている可能性がある。| nullと型付けされたフィールドは常に存在するが、値nullを保持している可能性がある。
{ "score": null }
export interface Root {
score: number | null;
}
ここでscoreは明示的なnullとともに存在するので、number | nullと型付けされる。値は存在し、ただそれがnullなのだ。これを配列の例のnick?: stringと対比してほしい。そちらはキー自体が欠けうる。APIがキーを省略しうるときは?:を、キーをnull値とともに送ってくるときは| nullを選ぼう。ほとんどの変換ツールでは、これがどう描画されるかをトグルで制御できる。
interfaceとtype:どちらを使うべきか
どちらもオブジェクトの形を記述できる。判断の仕方は次のとおりだ。
| 必要なもの | 使うもの |
|---|---|
| JSONからのプレーンなオブジェクトの形 | interface |
ユニオン(A | B)または交差(A & C) | type |
| ファイルをまたいだ宣言マージ/拡張 | interface |
| マップ型や条件型 | type |
| エディタのエラーメッセージがやや読みやすい | interface |
JSONオブジェクトから出てきたデータには、interfaceが慣例的な選択であり、コンパイラのエラーもわずかに見やすくなる。ユニオンが必要になった瞬間——たとえば成功かエラーのどちらかであるResult——typeに切り替えなければならない。インターフェースはユニオンを表現できないからだ。
type ApiResult =
| { status: "ok"; data: User }
| { status: "error"; message: string };
良いデフォルトはこうだ。プレーンなJSONオブジェクトにはinterfaceを生成し、形にユニオンや交差が必要になったらtypeへ変換する。完全な比較が見たければ、TypeScript Handbookがエッジケースまで網羅している。インターフェースではなくjson to typescript typeのエイリアスが必要なときは、ほとんどの変換ツールが出力全体を反転させる単一のトグルを備えている。
quicktype・json-to-ts・オンラインツール・手書きの比較
TypeScriptの型を生成する唯一最善の方法というものはない。JSONがどこにあるか、どれくらいの頻度で変わるかによる。
| アプローチ | 向いている用途 | トレードオフ |
|---|---|---|
| quicktype | 多言語への出力、ランタイムバリデーションコードの生成 | 重く、必要以上の出力になりがち |
| json-to-ts(ライブラリ) | スクリプトやパイプラインに組み込むビルド時コード生成 | セットアップとNodeツールチェーンが必要 |
| ブラウザベースのオンラインツール | 一回限りの変換、機密性の高いペイロード、インストール不要 | 毎回手で貼り付ける必要がある |
| 手書きで型を書く | 小さなオブジェクト、型システムの学習 | 規模が大きくなると面倒でミスしやすい |
複数言語の型が必要なとき、または型と並べてバリデーターを出力させたいときはquicktypeを選ぶ。変換をビルドステップに組み込むならjson-to-tsライブラリを選ぶ。手早い変換——とくにトークンや顧客ID、リモートサービスに貼り付けたくないものを含むペイロード——には、プライバシーと速度の点でブラウザツールが勝る。当サイトのJSON to TypeScript 変換ツールは完全にクライアントサイドで動く。JSONはページの外に出ず、インストールも更新も不要だ。
型はバリデーションではない:ランタイムチェックへの橋渡し
これは多くのチームがつまずくので、はっきり述べる価値がある。TypeScriptの型はコンパイル時に消去され、ランタイムでは何もしない。 生成されたinterface Userは、実際のAPIレスポンスがそれに一致するかをチェックしない。サーバーがidを数値ではなく文字列として送ってきても、TypeScriptはあなたの型注釈を素直に信じ込み、実データのほうが嘘をついている。
generate typescript typesし、かつそれをライブデータに対して強制するには、型をランタイムバリデーターと組み合わせよう。
- zod — スキーマを一度定義し、そこから静的な型を推論し、レスポンスをランタイムでパースする。
- io-ts — コーデックベースのバリデーション。関数型のコードベースで人気がある。
- JSON Schema + Ajv — 言語非依存のスキーマをランタイムで検証する。サービス間で契約を共有するときに便利だ。
よくあるパターンは、エディタ支援のためにインターフェースを生成し、実際の境界チェックとして一致するzodスキーマを書くことだ。
import { z } from "zod";
const UserSchema = z.object({
id: z.number(),
name: z.string(),
email: z.string().email(),
active: z.boolean(),
roles: z.array(z.string()),
});
type User = z.infer<typeof UserSchema>;
// 実際のレスポンスがスキーマに一致しなければ例外を投げる。
const user = UserSchema.parse(await res.json());
スキーマの道を行くなら、当サイトのJSON Schema バリデーション完全ガイドが、スキーマの記述から強制まで一通り解説している。
JSONを型付けするときのよくある落とし穴
生成された型は出発点であって、完成品ではない。次の点に注意しよう。
snake_caseとcamelCase。 変換ツールはキーをそのまま保持する。public_reposを持つGitHub風のペイロードは、publicReposではなくpublic_repos: numberを生成する。コードベースがcamelCaseを好むなら、snake_caseの型のまま付き合うか、入ってくる際にフィールドをリネームするマッピング層を追加するかのどちらかになる。
日付文字列はstringのまま。 "2026-06-01T00:00:00Z"のようなフィールドはDateではなくstringと型付けされる。これは意図的だ。JSONには日付型がなく、推測を外すのは正直であるより悪い。文字列からDateへの変換は、あなたが制御できるパース層に属する。
anyとunknownの漏れ。 空の配列はunknown[]になり、深く混ざった構造はゆるい型に劣化しうる。これらはバグではない。データが不十分で推論できないと変換ツールが認めているのだ。本当の形が分かったら手で締めよう。
深いネストの爆発。 重くネストされたペイロードは、小さなインターフェースの長い連鎖を生む。たいていそれで問題なく、一つの巨大なインライン型より読みやすいが、独自の名前に値しない形は平坦化する価値がある。
単一サンプルの罠。 これが大物だ。オプショナルなフィールドは複数の配列要素からしか推論できない。単一のオブジェクトでは、どのキーがときどき欠けるのかを変換ツールに伝えられない。まず代表的なレスポンスの配列を集めよう。変換前に複数のサンプルを並べて貼り付け、確認するにはJSON整形ツールが便利だ。そしてJSONCのような非標準の入力を扱うなら、当サイトのJSON5 から JSONC までを読んでほしい。変換ツールは厳密に正しいJSONを必要とする。
よくある質問
JSONをTypeScriptのインターフェースに変換するには?
JSONをJSON to TypeScript 変換ツールに貼り付ける。ブラウザ内で入力を読み取り、TypeScriptインターフェースを瞬時に生成する。「コピー」をクリックして結果を取得しよう。アップロードもアカウントもプラグインのインストールも不要だ。
JSONデータにはinterfaceとtypeのどちらを使うべき?
JSONからのプレーンなオブジェクトの形にはinterfaceを使う。慣例的であり、エディタのエラーもやや読みやすい。ユニオンや交差が必要なときはtypeに切り替えよう。インターフェースはそれらを表現できないからだ。
ネストされたオブジェクトや配列はどう扱われる?
ネストされたオブジェクトは別個の名前付きインターフェースになる(addressフィールドはAddressインターフェースを生む)。オブジェクトの配列はキーごとにマージされて一つの要素インターフェースになり、プリミティブの配列はstring[]のような型付き配列になる。
オプショナルなフィールドとnullのフィールドはどう型付けされる?
一部の配列要素から欠けているキーはオプショナル(nick?: string)として印が付く。常に存在するがnullを保持するキーは| null(score: number | null)と型付けされる。この2つは異なる状況を記述する。欠けているのか、存在するがnullなのか、だ。
TypeScriptの型はランタイムでJSONを検証する?
しない。TypeScriptの型はコンパイル時に消去され、ランタイムでデータをチェックしない。実際のAPIレスポンスを検証するには、生成された型をzod、io-ts、あるいはJSON SchemaとAjvといったランタイムバリデーターと組み合わせよう。
quicktype・json-to-ts・オンライン変換ツール——どれが最善?
quicktypeは多言語への出力とランタイムバリデーターに向く。json-to-tsライブラリはビルド時コード生成に向く。オンライン変換ツールは手早く、プライベートな、一回限りの変換にインストール不要で向く。機密性の高いペイロードには、クライアントサイドのブラウザツールがデータをどのサーバーにも置かずに済む。
なぜ日付文字列はDateではなくstringと型付けされる?
JSONには日付型がないため、日付は通信上ただの文字列だ。stringと型付けするのは正直で安定している。Dateへの変換は、フォーマットとエラー処理を自分で制御できるパース層での判断だ。
オンライン変換ツールを使うとき、JSONデータはプライベート?
クライアントサイドのツールなら、そうだ。変換はJavaScriptを使ってブラウザ内で完全に実行されるため、JSON——トークン、ID、顧客データを含めて——はページの外に出ず、サーバーに送られることもない。