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.

[ Ad slot — replace with AdSense / Ezoic code ]

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

[ Ad slot — replace with AdSense / Ezoic code ]

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.