Generate TypeScript interfaces from any JSON in your browser: nested objects, arrays, union types, optional keys, and null-aware fields. Private, no uploads.
Runs entirely in your browser — your data never leaves your device.
How to use JSON to TypeScript
What it does & when you need it
You hit an API, get back a wall of JSON, and now you need TypeScript types so the
compiler can catch a typo before it ships. This tool reads any JSON value and
generates matching interface declarations — one per object shape — so you can
paste them straight into a .ts file and start getting autocomplete and
type-checking on the response. It infers types rather than copying values, so the
output stays correct as the data changes, and it does everything in your browser,
so an unreleased payload never leaves your machine.
How to use
Paste JSON into the input.json buffer, press Sample for an example, or
Upload a .json file.
Optionally set a Root name — the top-level interface is Root by default,
but User or ApiResponse often reads better.
Copy the generated interfaces from types.ts with Copy TypeScript or
Ctrl/Cmd + Enter.
Things worth knowing
Nested objects get their own interfaces. Rather than one deeply inlined type,
each nested object becomes a named interface referenced by the field above it,
which is far easier to reuse and read. Names come from the key, so a users
array yields a User element interface.
Arrays are merged intelligently. An array of objects is collapsed into a
single element interface: keys present in only some items become optional with a
?, mirroring real payloads. A mixed array like [1, "a"] becomes
(number | string)[], and an empty array falls back to unknown[].
Null is tracked. Wherever null appears, it is added to the field's type as
| null, so you handle it deliberately instead of hitting a runtime surprise.
A non-object root becomes a type alias. Interfaces only describe objects, so a
top-level array or primitive is emitted as export type Root = … instead. Need
to reshape the JSON first? Run it through the
JSON Formatter.
Emits Root, User, and Address interfaces, each referenced by the field above it.
Array of records with a missing key
{"items":[{"id":1,"label":"A"},{"id":2}]}
The two objects merge into one Item interface where label is optional (label?: string).
Nullable and mixed values
{"nickname":null,"scores":[10,null,"n/a"]}
Shows nickname: null and a unioned array scores: (number | string | null)[].
Frequently asked questions
How are nested objects and arrays typed?+
Each nested object becomes its own named interface referenced by the parent field, so you get a flat list of interfaces rather than one giant inline type. Arrays become T[]: an array of objects is merged into a single element interface, and a mixed array like [1, "a"] becomes (number | string)[].
What happens to null values and keys missing from some objects?+
A null value contributes | null to the field type, so [1, null] yields (number | null)[]. When you convert an array of objects, keys that appear in only some of them are marked optional with a ? — the interface is the union of every key seen, which mirrors real API payloads.
Can I rename the top-level interface?+
Yes. The root interface is called Root by default; set your own root name such as User or ApiResponse. Nested interfaces are named after their key (a users array produces a User element interface), and any name clash is de-duplicated with a numeric suffix.
Why is my root emitted as a type alias instead of an interface?+
Interfaces can only describe objects. If the top level of your JSON is an array or a primitive, the tool emits a type alias instead — export type Root = string; for a bare string, or export type Root = RootItem[]; for an array, with RootItem holding the element shape.
Are numbers typed as literals, and is my JSON uploaded?+
Numbers are widened to number (JSON has no integer/float distinction) and booleans to boolean — the tool infers reusable types, not literal values. Everything runs locally in your browser, so nothing you paste is ever sent to a server.