JSON to TypeScript converter
Paste JSON and get TypeScript interfaces or type aliases plus a Zod schema, with optional keys and unions inferred. Free, no sign up, runs in the browser.
Valid JSON. 3 types, 14 properties.
- Nested objects become named types
- Arrays of objects are merged, keys missing from some items become optional
- Mixed arrays become union element types
- null stays null so you can decide the real type
export interface Invoice {
id: string
status: string
customer: Customer
lines: Line[]
tags: (string | number)[]
paid: boolean
metadata: Record<string, unknown>
}
export interface Customer {
name: string
email: string
vat_number: null
}
export interface Line {
sku: string
qty: number
unit_price: number
note?: string
}
How to use it
- 1Paste a JSON object or array, for example an API response.
- 2Name the root type and choose interfaces or type aliases.
- 3Switch on readonly if the data should not be mutated.
- 4Copy the TypeScript, or open the Zod tab for a runtime schema.
How the types are inferred
The tool walks the JSON once and records a shape for every value. Objects become named types, with the name taken from the key: customer becomes Customer, and the items of lines become Line. Arrays of objects are merged into one shape: a key missing from some items is marked optional with ?, and a key that holds different types becomes a union such as string | number. Two objects with the same keys and types share one declaration. null stays null. A sample cannot tell you whether "avatar": null is really string | null, so the output keeps the fact and leaves the decision to you. Empty objects become Record<string, unknown> and empty arrays unknown[] for the same reason.
export interface Invoice {
id: string
customer: Customer
lines: Line[]
tags: (string | number)[]
}
export interface Line {
sku: string
qty: number
note?: string
}
Interfaces can be extended and merged across declarations, which suits API models that grow, while type aliases express unions and intersections directly. For plain data either works, so pick the one your codebase already uses. The readonly option adds readonly to every property and array, which stops accidental mutation of fetched data.
The Zod tab
Types vanish at runtime, so a response that drifts from the sample passes the compiler and fails in production. The Zod tab prints the same shapes as schemas, dependencies first, with .optional() and .nullable() where the sample needs them, and derives the TypeScript type from the root schema with z.infer. Validate at the boundary with InvoiceSchema.parse(json) and the rest of the code can trust the type.
When the JSON is wrong
The parser is strict JSON, so trailing commas, single quotes, comments and unquoted keys are reported with a line and column, and the offending line is shown with a caret. Those are the usual mistakes when JSON is copied out of JavaScript, and the message names which one it is.
Frequently asked questions
Does the JSON leave my browser?
No. Parsing and type generation run locally. Nothing is stored or sent.
How are optional properties detected?
Only by sampling. When an array holds objects and a key is missing from some of them, it becomes optional. A key present everywhere in the sample is required, even if your API sometimes omits it, so review the result against the API docs.
Does the Zod output work with Zod 4?
Yes. The schema uses z.object, z.array, z.union, z.record with two arguments, .optional(), .nullable() and .readonly(), which behave the same in Zod 3 and 4.