DevLab
{}
JSON⭐ Popularintermediate

JSON to TypeScript

convert JSON objects to TypeScript interfaces automatically

By Bikram NathLast updated

Paste a raw JSON object and get TypeScript interface declarations back. Nested objects become separate named interfaces, arrays become T[], and any field holding null gets typed as T | null. Useful when a teammate hands you an undocumented API response and you need to type it before wiring it into a service layer. Unlike quicktype, there is no CLI install or schema export step needed for a one-off conversion.

Try it now — free, instant, no signup

What is JSON to TypeScript?

This converter reads a JSON value, infers the TypeScript type of each key, and emits interface declarations you can paste directly into a .ts file. Give it {"user":{"id":1,"roles":["admin","viewer"]}} and you get a Root interface with a user field typed to a User sub-interface, where id is number and roles is string[]. The nesting depth is followed automatically, so deeply nested API payloads produce a set of small, flat interface files rather than one giant inline object type.

For a simple one-off conversion, when you have a Postman response and need interfaces in under a minute, this removes the install and config overhead. quicktype (quicktype.io) is the right reach when you need class output, Zod schemas, JSON Schema, or reproducible multi-language generation inside CI. json2ts.com covers similar ground but provides fewer type-narrowing notes on ambiguous fields like null or mixed arrays.

One important gotcha: types are inferred from the single sample you paste. If a field is null in your sample but is actually a string at runtime, the generated interface will read field: null instead of field: string | null. Always use a representative sample that includes non-null values for every field you care about, or plan a manual review pass on any null-typed field in the output.

When to use JSON to TypeScript

Type a third-party REST API response by pasting one Postman sample before wiring it into a TypeScript fetch call.
Generate a config interface from an existing JSON settings file so IDE autocomplete covers every key.
Document an undocumented internal backend payload by pasting a live response and committing the resulting interfaces to the repo.

Frequently Asked Questions

What happens when a JSON array contains objects with different shapes?
The converter typically merges the shapes into a single interface, marking any key absent from at least one object as optional. For example, [{"id":1,"name":"Alice"},{"id":2}] yields an interface where name is string | undefined. If the objects differ so drastically that a merged interface looks wrong, split the array into typed variants manually and use a discriminated union. The single-sample heuristic breaks down most visibly on polymorphic arrays where different items carry entirely different key sets.
Why does the output use `number` for fields I know will always be whole integers?
TypeScript has no integer type at the language level. Both JSON 42 and JSON 3.14 map to number, because the type system makes no distinction between integer and float values. The converter follows the spec faithfully. If downstream code needs integer-only guarantees — for example, a database row ID — add a branded type like type UserId = number & { __brand: 'UserId' } manually after generating the base interface. That constraint cannot be inferred from a JSON sample alone.
Does the converter produce one flat interface or separate named interfaces for each nested object?
Separate named interfaces. A nested object at user.address is extracted into its own Address interface, and the parent references it as address: Address. This keeps each interface small and independently importable — another module that only needs Address can import it without pulling in the entire Root type. Names are typically derived from the JSON key, capitalised. Very deeply nested structures produce a chain of interfaces, each referencing the next, which is generally easier to maintain than a single type with deeply nested inline object literals.
What happens to JSON keys that are not valid TypeScript identifiers, like `content-type` or `x-request-id`?
Keys containing hyphens, dots, or leading digits are not valid bare identifiers in TypeScript. They need to be quoted in the interface so the output reads 'content-type': string rather than content-type: string. Quoted keys are fully valid TypeScript and behave identically at the type level. The only downstream effect is that you access them with bracket notation in your code: headers['content-type'] rather than headers.contentType. If you want camelCase property names, rename the keys in the JSON before pasting it into the converter.
How does the tool decide which fields to mark optional with `?`?
Optionality is inferred purely from the sample you provide. If you paste an array of objects and a key is absent from at least one of them, that field is typed as optional. If you paste a single object, every key present is treated as required because there is no evidence of absence in the sample. This means a single-object paste almost always produces an all-required interface. To get realistic optionality, paste an array of several representative objects that includes cases where nullable or conditional fields are actually missing, not just set to null.

Related Tools