Skip to main content
JT

JSON to TypeScript Interface Generator

Paste a JSON sample and generate matching TypeScript interfaces, with nested objects automatically split into their own named types.

Did you like the tool? Thanks!
Share:


    

How to Use JSON to TypeScript Interface Generator

Paste a JSON object or array and the tool infers a TypeScript `interface` declaration that matches its shape. Nested objects become their own named interface, derived from the key they were found under (e.g. an `address` object becomes `interface Address`); arrays become `Type[]`, with a union of element types if the array contains a mix of shapes; primitives map directly to `string`, `number`, or `boolean`, and `null` values become `Type | null`.

About JSON to TypeScript Interface Generator

Hand-writing TypeScript interfaces to match an API response or a JSON config file is repetitive, easy to get subtly wrong (a typo'd property name doesn't error until you actually use it), and quickly gets tedious for anything with more than a couple of nested objects. This tool automates the first draft: paste a real JSON sample — an actual API response is ideal — and it walks the structure recursively, producing one or more `interface` declarations that describe exactly the shape you pasted. The recursive naming behaviour is the part that makes the output genuinely usable rather than a single giant, deeply-nested inline type. When the tool encounters a nested object, it doesn't inline that object's shape into the parent interface as an anonymous type — instead it generates a separate, named `interface` for it, deriving the name from the property key it was found under (converted to PascalCase: a key called `address` produces `interface Address`, a key called `billing_info` produces `interface BillingInfo`), and references that name from the parent (`address: Address;`). This mirrors how you would naturally structure hand-written TypeScript, keeping each interface focused and giving you meaningful, reusable names instead of one unreadable nested blob. Arrays are handled by inspecting every element and inferring the element type: an array of plain strings becomes `string[]`, an array of numbers becomes `number[]`, and an array of objects generates a named interface for the object shape (again derived from the parent key, typically singularised informally by just reusing the same PascalCase key name) and produces `KeyName[]`. If an array contains a genuine mix of element types — some strings, some numbers — the tool falls back to a union type, `(string | number)[]`, rather than picking one arbitrarily and silently dropping information about the others. Primitive JSON values map onto TypeScript's built-in types directly: JSON strings become `string`, JSON numbers become `number` (TypeScript, like JSON, does not distinguish integers from floats at the type level), JSON booleans become `boolean`, and a JSON `null` value for a given property is represented as `Type | null` using whatever type the tool infers from other array elements or, for a lone null with no other information, `unknown | null`. Worth being upfront about: this is best-effort inference from a single sample, not schema validation. If a property is `null` in your sample but would actually hold a string in other API responses, the tool has no way to know that unless you paste a sample where it appears as a string — it can only describe what it sees. Likewise, TypeScript's `?` optional-property marker is not applied to anything, because a single object gives no signal about which fields are sometimes absent versus always present. A natural next step, deliberately left out of this simple version, would be accepting an array of multiple sample objects and diffing which properties are present across all of them versus only some — marking the latter as optional — but that is a meaningfully more complex feature and out of scope here.

Details & Tips

Example — input: `{"id": 1, "name": "Alice", "active": true, "address": {"city": "London", "postcode": "E1 6AN"}, "tags": ["admin", "eu"]}` Generated output: ``` interface Address { city: string; postcode: string; } interface Root { id: number; name: string; active: boolean; address: Address; tags: string[]; } ``` The outermost interface is named `Root` when the input is a plain object with no natural parent key to derive a name from; if the pasted input is itself an array of objects, the tool instead generates a single interface (also named from context, defaulting to `Root`) and wraps the whole thing as `Root[]` at the point of use. Name collision handling: interface names are derived from the property key they were found under, so this only collides when the same key name is reused for a nested object at two different places in the structure — for example, `{"address": {...}, "contact": {"address": {...}}}` has an `address` key at the root and another `address` key nested inside `contact`. Both would naturally generate `interface Address`, so the tool appends a numeric suffix to the second one it encounters (`Address`, `Address2`) and points the `contact.address` property at the correctly suffixed interface. Empty arrays produce `unknown[]`, since there is no element present to infer a type from — replace this manually with the correct type once you know what the array is meant to hold. Deeply nested structures (objects within objects within arrays) are fully supported; the recursion has no artificial depth limit, only the practical limit of how large a JSON sample you paste in. Limitations, restated plainly: no optional-property detection (everything is treated as always present, since only a single sample is analysed); no detection of union types across multiple samples of the same interface; number types are not narrowed to more specific TypeScript patterns like literal types or enums, even if every sample value happens to come from a small fixed set; and date-like strings (ISO 8601 timestamps, for example) are typed as plain `string`, not `Date`, since JSON itself has no date type and the tool infers only from the JSON value's own type, not from string content heuristics. A Copy button copies the full generated interface block to your clipboard.

Frequently Asked Questions

How are nested objects converted?
Each nested object becomes its own named TypeScript interface, with the name derived in PascalCase from the property key it was found under — for example, an "address" object generates "interface Address" and is referenced as address: Address; in the parent.
How are arrays handled?
The tool inspects every element to infer a type. A uniform array becomes Type[]; an array of objects generates a named interface for the object shape and produces Name[]; a genuinely mixed array becomes a union type like (string | number)[].
Does it detect optional fields?
No — this simple version infers types from a single sample object or array, so it has no way to know which fields are sometimes missing. Every property is treated as required. Sampling multiple objects and diffing which fields are present in all of them is a possible future enhancement, out of scope here.
What happens with a null value?
A property that is null in your sample is typed as Type | null, using whatever type can be inferred from context, or unknown | null if there is no other information available.
What if my JSON sample is an array at the top level rather than an object?
The tool generates the interface for the element shape and represents the whole input as Name[] wherever it is referenced.
What happens if two nested objects would generate the same interface name?
The tool appends a numeric suffix (Address, Address2, and so on) to keep every generated interface name unique, and updates all references accordingly.
Does it validate that my input is valid JSON first?
Yes. Invalid JSON shows a parse error with the position of the problem before any interface generation is attempted.
How are ISO date strings typed?
As plain string. The tool infers types from the JSON value's own type only, and JSON has no native date type, so it does not attempt to detect date-like string patterns.
What does an empty array generate?
unknown[], since there are no elements to infer a type from. Replace it manually with the correct element type once known.
Can I copy the generated interfaces?
Yes, a Copy button copies the full block of generated interface declarations to your clipboard, ready to paste into a .ts file.
Is my JSON sent to a server to generate the types?
No. Type inference runs entirely in your browser using JavaScript — nothing you paste is uploaded anywhere.

Part of These Collections

Also Available As

json to typescript, json to interface, typescript interface generator, generate typescript types from json, json to ts

Found a Problem?

Let us know if something with JSON to TypeScript Interface Generator isn't working as expected.

Thanks — we'll take a look.