JSON to TypeScript
The result appears here.
Generate
Your document never leaves the browser.
Types in ten languages from JSON, YAML, XML or CSV — generated in your browser, never uploaded.
Choose what the source is and which language you want, then paste a document. The types are written while you type, from every record in it, and the JSON they were inferred from sits one tab away.
The picker offers TypeScript, Python, JSON Schema, Java and C# as tabs, and More holds Go, Zod, Rust, Kotlin and Swift. All ten read one inferred model of the data, so a field missing from some records is optional in every language at once, and a nested object gets its own named type in each of them.
This is the generator behind Generate in the editor, not a copy of it. The same document gives the same code here and there, and a language option set on one page is already set on the other.
Two users, one of them without an email
[
{ "id": 1, "name": "Ada", "email": "ada@example.com" },
{ "id": 2, "name": "Alan" }
]TypeScript
export interface RootItem {
id: number;
name: string;
email?: string;
}
export type Root = RootItem[];Go, from the same inference
package main
type RootItem struct {
ID int64 `json:"id"`
Name string `json:"name"`
Email *string `json:"email,omitempty"`
}
type Root []RootItemCode is never generated from YAML, XML or a spreadsheet directly. Each is first read into JSON by the reader Convert uses, and the types are inferred from that JSON. When the source is not JSON, the row says so — From, then JSON, then the language — and the result gains a JSON tab beside the code.
Showing the step matters because reading decides the types. A CSV cell written as 42 becomes a number and one written in quotes stays a string; an XML element holding 42 is a string unless number detection is on. When a type looks wrong, the JSON tab shows which reading produced it, and it can be copied, downloaded or opened in the editor.
CSV, with From set to CSV and the language TypeScript
sku,qty,code
PEN-01,2,"42"
INK-07,1,"07"The JSON tab, the step the types are inferred from
[
{
"sku": "PEN-01",
"qty": 2,
"code": "42"
},
{
"sku": "INK-07",
"qty": 1,
"code": "07"
}
]The TypeScript, written from that JSON
export interface RootItem {
sku: string;
qty: number;
code: string;
}
export type Root = RootItem[];XML, with From set to XML and the language TypeScript
<order>
<id>7</id>
<item>pen</item>
</order>With Always make arrays for: item, and Detect numbers and booleans on
export interface Order {
id: number;
item: string[];
}
export interface Root {
order: Order;
}Option
Read XML: which elements always become arrays, even when one appears only once, and whether numbers and booleans are detected in text.
Option
Read CSV or TSV: the delimiter, guessed or chosen, and whether the first row holds the column names.
Option
The language: TypeScript’s interface or type alias and its optional-field spelling, Python’s Pydantic, dataclass or TypedDict style, the package for Java and Go, the namespace for C#, and the rest, each under its own name.
Beside Language, a second row named Structured output offers OpenAI, Claude and Gemini. Each writes the schema that provider’s API takes for structured output, so the model answers in the shape of your sample rather than in free text. Output chooses between the bare schema and a request fragment to merge into the body of your own call.
OpenAI’s fragment fits the Responses API or Chat Completions, Claude’s is either JSON output or a strict tool, and Gemini’s fits generateContent or the Interactions API. The API and Use controls, and a name where the request carries one, appear only while Output is Request fragment, since the bare schema has no use for them.
A provider schema is stricter than the JSON Schema target, so a few things change to fit. OpenAI wants every property listed as required, so a field missing from some records stays required and accepts null instead. For OpenAI and Claude, a root that is not an object, such as a list of records, is wrapped as a required property named items. A record, an object used as a map from ids to values, becomes for those two a list of key and value pairs whose values are JSON text, to be parsed back after the answer arrives.
The list under the schema says which of these changes happened, and at which path, and warns when a provider limit is near: Claude’s 24 optional properties, for one, or OpenAI’s ten levels of nesting. Nothing on this page calls a provider. The schema is written in the tab, and you send it with your own key from your own code.
A list of two users, one of them without an email
[
{ "id": 1, "name": "Ada", "email": "ada@example.com" },
{ "id": 2, "name": "Linus" }
]OpenAI’s schema for it. The list is wrapped as items, and email is required but may be null
{
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"$ref": "#/$defs/RootItem"
}
}
},
"required": [
"items"
],
"additionalProperties": false,
"$defs": {
"RootItem": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
},
"email": {
"type": [
"string",
"null"
]
}
},
"required": [
"id",
"name",
"email"
],
"additionalProperties": false
}
}
}Generating from one branch of a large response, rather than the whole of it, needs a tree to pick the branch from. Open the JSON in the editor, choose a node in the Tree view, and Generate proposes a type name from its path.
Reading, inference and code generation all happen in this tab. Payloads full of customer records can be turned into types without leaving the machine, and with the connection off the page carries on working once it has loaded.
Yes. Set From to YAML, or paste the whole file and let the page recognise it. The YAML is read as YAML 1.2, so yes and no stay strings, and the code is generated from the JSON it becomes.
Because at least one cell in it was quoted or held text. The JSON tab shows each cell as it was read, which is the quickest way to find the one that made the column a string.
Mistral, Groq, xAI and other OpenAI-compatible APIs take the Chat Completions request shape, so choose Chat Completions under API. Each of them documents which schema keywords it honours, and that list is worth reading before relying on a particular one.
For this browser tab only. A reload keeps the document and the language; a new tab opens on JSON and TypeScript with an empty source.