JSON to TypeScript Converter

Paste sample JSON and get TypeScript interfaces, type aliases, or classes — with nested objects named sensibly, array element types inferred as unions, and fields marked optional when they're missing from some array samples. Live, in your browser.

The core idea: a JSON sample implies a shape. {"id": 1, "name": "Ada"}  →  interface Root { id: number; name: string; } The interesting work is in the edge cases — nulls, mixed arrays, keys that come and go — and this converter handles those explicitly rather than emitting any.

Type generation runs entirely in your browser — API responses you paste here are never uploaded. Shareable links only include inputs under 1,500 characters.

How the types are inferred

The converter walks your JSON and maps values to TypeScript types: strings, numbers, booleans, null, arrays, and objects. The judgment calls are documented here so you know exactly what you're getting:

One inherent limitation of sample-based generation is worth stating plainly: the type describes your sample, not the API contract. If the sample happens to omit a field that's usually present, or a number field happens to be an integer in every sample you pasted, the generated type reflects that. Paste a response with multiple array items — or several representative responses wrapped in an array — and the merger does noticeably better.

JSON Schema input — what's supported

If you paste a JSON Schema instead of a JSON sample (detected by $schema, or a type/properties structure), the converter switches to schema mode and handles the basics: type, properties + required (unrequired properties become optional), items for arrays, enum (emitted as a union of literals), const, nullable via type: ["string","null"], and $ref to #/definitions/… or #/$defs/… within the same document.

Not supported, stated honestly rather than half-implemented: allOf/anyOf/oneOf composition, external $refs, patternProperties, conditional schemas (if/then), and format-driven refinements. If your schema uses those, the affected part is emitted as unknown with a comment naming the unsupported keyword — you'll see exactly where hand-editing is needed. For full-fidelity schema conversion, a dedicated compiler in your build pipeline is the right tool; this page covers the quick-look case.

Generated types are a starting point

Treat the output as scaffolding you review, not gospel. Things worth checking by hand: fields you know are enums but the sample shows as plain strings (tighten status: string to status: 'active' | 'archived'); date strings, which JSON can't distinguish from other strings (they arrive as string, not Date — parse at the boundary); and ID fields where you may want branded types. The generator gets you 90% of the way in a second; the last 10% is where your domain knowledge belongs.

Related tools

Frequently asked questions

Should I use interface or type?

For object shapes like these, they're nearly interchangeable, and most teams pick one for consistency. Practical differences: interfaces can be extended and re-opened via declaration merging (useful for augmenting library types), and error messages sometimes read better; type aliases can express unions, intersections, and mapped types that interfaces can't. A common convention: interface for object shapes, type for everything else. Both toggle options here produce identical runtime behavior — there is none; types are erased at compile time.

How exactly are optional fields inferred?

When merging the objects inside an array, a key present in some items but absent in others becomes optional (key?:). A key present in every item but sometimes null becomes key: T | null — not optional, because it was always there. If a key is both sometimes missing and sometimes null, you get key?: T | null. Outside arrays there's only one sample per object, so nothing can be inferred as optional — every key you pasted is required. To get optionality detected, provide an array of representative samples.

Why unknown[] instead of any[] for empty arrays?

Because any switches the type checker off for everything the value touches, while unknown keeps it on: you must narrow (or assert) before using the elements, which is exactly the reminder an empty sample deserves. If you know the element type, replace it — that's a one-word edit.

Does the class output validate the JSON at runtime?

No — and neither does any TypeScript type. Types are erased at compile time; a class here gives you a constructor that copies fields from a parsed object, but it doesn't check them. If you need runtime validation of untrusted JSON, pair the generated types with a schema validator or a parsing library in your codebase; the types keep you honest at compile time, the validator at runtime.

Is my JSON sent to a server?

No. The inference and code generation are JavaScript running in this page — verify in DevTools' Network tab, or load the page and go offline. Real API responses often contain user data, which is exactly why this stays client-side.