メインコンテンツへ移動

JSONをTypeScriptに変換

「JSONをTypeScriptに変換」は、サンプルのドキュメントからインターフェースをブラウザ内で生成します。1件だけではなく、手元のレコードをすべて貼り付けてください。一部のレコードにしか現れないフィールドは、サンプルを横断して初めて検出できます。実行時に存在しない必須メンバーではなく、省略可能なメンバーになります。

端末内で処理
形式
サンプルJSON
0 B1 行行 1、列 1
構文エラー · 1行1列でエラー

ドキュメントが途中で終わっています。切れている可能性があります。


^
生成されたコード読み取り専用
0 B1 行
複数のレコードがあれば貼り付けてください。一部の行にだけあるフィールドを検出し、正しい省略可能な型を生成できます。

JSONをTypeScriptに変換はどう動きますか?

このジェネレーターは、サンプルから1つの中間的な型モデルを作り、それを描画します。実装の詳細のように聞こえますが、出力が正しい理由です。このフィールドは省略可能か、この2つのオブジェクトは同じ型か、混合配列の要素の型は何か——本当に難しい決断は、値に出会うたびに導き直すのではなく、1か所で1度だけ答えられます。

省略可能なフィールドは、レコード間の不一致から来る

[{"a":1}, {"a":1,"b":2}]のような入力に対し、素朴な実装は最初の要素を読んで{ a: number }を出力し、bを黙って失います。正しいやり方は、全要素のフィールド集合を統合することです。aは両方に存在するので必須、bは片方にしか現れないのでb?: numberになります。これはジェネレーター間の最大の違いであり、レコードを1件だけ貼り付けると「あなたのAPI」ではなく「1件のレコード」を記述する型ができる理由です。

同じ形は50個ではなく1つの型にまとめる

すべてのオブジェクトは、その構造(キー名、省略可能性、値の型それぞれのフィンガープリント。順序は問わない)で指紋化されます。50人の顧客が、それぞれ同じ形のaddressを持つドキュメントは、AddressからAddress50までではなく、1つのAddressインターフェースになります。名前はオブジェクトを保持していたキーから取られ、配列を保持していた場合は単数形化されます。"users": [{…}]はUserを生成します。

nullはnull許容の表現であり、型ではない

あるレコードでは数値、別のレコードではnullというフィールドは、生成した名前のユニオン型ではなくnumber | nullとして出力されます。すべてのレコードでnullのフィールドには、正直にunknownと、その旨を伝えるコメントを出力します。nullと出力すればサンプルについては正確ですが、データについては無用なものになるからです。

数値はnumber、ただし注記付き

TypeScriptの数値型は1つなので、整数も浮動小数点もnumberになります。それでも、32ビットの型には大きすぎる整数はコメントで印を付けます。同じモデルがGo、Java、C#のジェネレーターも駆動していて、そこではこの区別がintとint64の分かれ目になるからです。そして、64ビットのIDがそもそもJavaScriptに届いていることは、知っておく価値があります。

サンプル

[
  { "id": 1, "name": "Ada", "deleted_at": null },
  { "id": 2, "name": "Grace", "deleted_at": null, "team": "ops" }
]

生成結果

export interface User {
  id: number;
  name: string;
  deleted_at: unknown; // only null in the sample
  team?: string;
}

JSONをTypeScriptに変換が対応するオプションとエッジケースは?

技術リファレンスとオプション
パラメータ型デフォルト動作とエッジケース
ルート型識別子Rootトップレベルの型の名前です。配列のルートはName[]として報告され、その内部にあるオブジェクトの形状はそれらを保持するキーに基づいて名前が付けられます。
interface / type宣言interfaceインターフェースは宣言のマージをサポートし、オブジェクトの形状に関するより良いエラーメッセージを生成します。型エイリアスは、後でユニオンやマップされた型が必要な場合に必要です。どちらもここでは有効です。
readonly真偽値offすべてのメンバーをreadonlyとしてマークします。解析されたAPIレスポンスには有効で、コード内の何もそれをインプレースで変更すべきではない場合にオンにすると良いでしょう。
camelCaseキー真偽値offsnake_caseキーをリネームし、元のキーを末尾のコメントに記録します。パイプライン内の何かが実際にキーをリネームしている場合にのみ正しく、生成された型はそうでなければJSONと一致しなくなります。
オプショナリティ推論全レコードから推定同じ形状の少なくとも1つのレコードに存在しないキーはオプショナルになります。複数のレコードを貼り付けてください。1つのレコードではこれを表現できません。
Nullable推論nullとのunionあるレコードではnullで、他のレコードではstringである値はstring | nullになります。存在しないこととnullは異なるもので、異なる方法で報告されます。
混合配列union括弧付き混合スカラーの配列は(string | number)[]になります。括弧は重要です:string | number[]は全く別の意味を持ちます。
入力サイズbytes2 MB推論ではすべての値が読み取られます。数百の代表レコードで百万個と同じくらいの形状を説明できるため、実際には上限はコストになりません。

よくある質問

APIが常に送っているフィールドが省略可能になるのはなぜですか?

貼り付けたサンプルの中の少なくとも1件のレコードに、そのフィールドがなかったからです。ジェネレーターは、与えられたデータしか記述できません。本当に常に存在するフィールドなら、常に現れているサンプルを貼り付けてください。あるいは?を手で削除しても構いません。サンプルより契約をよく知っているのがあなただったら、それが正しい判断です。

レコード1件とレスポンス全体、どちらを貼り付けるべきですか?

レスポンス全体、できれば複数です。省略可能性、null許容、混合型はすべて、1件のレコードではなくレコード集合の性質です。レコードを1件だけ与えられたジェネレーターには、常に存在するフィールドと、たまたま今回は存在したフィールドの区別がつかず、最も気付きにくい形で間違った型を自信満々に出力します。

実際の型ではなくunknownになったのはなぜですか?

その位置のサンプルがすべてnullだったからです。推論の材料が何もないのです。代替案はさらに悪い結果になります。型としてのnullはサンプルについては正確でもデータについては無用ですし、anyはそれより先のすべての型チェックを無効にします。unknownは、使う前に型を絞ることを強制します。型が本当に未知である場合の正しい結果です。

型だけでなく実行時のバリデーターも生成できますか?

できません。TypeScriptの型はコンパイル時に消えるため、サンプルから生成したインターフェースは、実行時に実際に受け取ったレスポンスについては何も保証しません。注釈ではなく保証が必要なら、代わりにJSONスキーマを生成してそれに対して検証するか、Zodのスキーマを手書きしてください。生成したインターフェースを検証だと見なすのは、よくある、そして高くつく間違いです。

深くネストしたドキュメントや再帰的なドキュメントも処理できますか?

ネストは、深さ100まで対応します。それ以上は出力されるコードが使い物にならないので、スタックオーバーフローではなく明確な上限があります。真の再帰(コメントの中にコメントが入る構造)は、サンプルが示す範囲で推論します。サンプルが3階層なら3階層になります。データの中に、この構造が永久に繰り返すという情報はないからです。

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

いいえ。推論も生成も、すでに開いているタブの中で実行されます。DevToolsを開き、貼り付け中にNetworkパネルを見てください。ほとんどのツールよりここでは重要です。変換されるドキュメントは本番APIのレスポンスで、実際の顧客レコードが入っていることも多いからです。