ToolsForWeb

JSON to TypeScript

Paste JSON and get matching TypeScript types: objects become interfaces, arrays of objects with differing keys get optional markers, mixed arrays become union types, and deeply nested objects are extracted into named child interfaces. Keys that are not valid identifiers are quoted, interface names are sanitized, and untyped values emit unknown — never any. Runs entirely in your browser.

Loading tool…

About this tool

Converts a JSON document into TypeScript type declarations that describe it exactly: objects become interfaces, keys become PascalCase interface names, and arrays become either a uniform element type or a union of what the array actually contains. Objects in an array are merged into one shape with optional (?) markers on keys that only some rows have. Nesting stays inline to three levels; deeper objects are extracted into named child interfaces. Values that JSON cannot type emit unknown, never any, so the output never silently disables type checking.

When to use it

Typing an API response so editors can check the code that consumes it.
Bootstrapping types from a config file or a JSON Schema-less endpoint.
Seeing the real shape of a large JSON document, including which fields are inconsistent.
Generating interfaces to refine by hand instead of writing them from scratch.

Questions

Why does a field show as optional?

Because the same key is missing from at least one sibling object in an array. Merging those shapes without a ? marker would lie about the data — accessing that field on the shorter rows would crash at runtime.

Why unknown instead of any?

any turns the type checker off for everything downstream, which defeats the point of generating types. unknown keeps the hole honest: the compiler forces you to narrow it before use, which is exactly where a human decision belongs.

Are the generated names guaranteed unique?

Yes — collisions from similar keys (item, Item) get a numeric suffix, non-identifier keys are quoted rather than mangled, and child interfaces are emitted after the root so the output compiles as-is when pasted into a .ts file.

Related tools