JSON to TypeScript Interface Generator
Generate TypeScript interfaces from a JSON example. Inspect nested objects and arrays, then refine the inferred types for your actual data contract.
JSON to TypeScript Interface Generator workspace
Try a Sample
Nested Interface Generation
Each nested object becomes its own named interface — easier to import, reuse, and refactor than a single 500-line anonymous type. Names are deduplicated automatically.
Full Style Control
Toggle `interface` vs `type`, `export` keyword, semicolons, root-name override, and array union behavior. Match your team's exact lint config without touching the output.
Heterogeneous Array Unions
When an array contains mixed types (`["a", 1, true]`), we emit a proper TypeScript union: `(string | number | boolean)[]`. No data loss, no `any` escape hatches.
100% Client-Side
Type inference runs in your browser. API responses with auth tokens, customer PII, or internal schema details never leave your device.
JSON to TypeScript: Generate Interfaces and Types from Any JSON
Generate TypeScript interfaces from a JSON example. Inspect nested objects and arrays, then refine the inferred types for your actual data contract. One JSON example cannot establish all possible values. An absent field may be optional, an empty array reveals little about its items, and a number in a sample may represent an identifier. Review the generated types against real API documentation and boundary cases.
How to use the JSON to TypeScript converter
- Paste valid JSON into the input — an API response, a config blob, or a sample payload. The output updates instantly.
- Set a meaningful Root Name (for example
StripePaymentIntent) so the top-level type reads well. - Choose interface or type as the declaration style to match your team's lint config.
- Toggle export, semicolons, and Array Unions to fit your code style.
- Press Copy to grab the generated TypeScript, then refine: tighten nullable fields, narrow string literals, add
readonly.
How JSON-to-TypeScript inference works
The tool parses your input with the browser's native JSON.parse — so it accepts exactly the grammar defined by RFC 8259 and ECMA-404 (the two specs that define JSON). It then walks the parsed tree and emits a type for each node. JSON has only six value kinds — string, number, boolean, null, object, array — which is why inference is reliable: there is a small, fixed mapping to TypeScript primitives, named interfaces, and array types.
One JSON quirk to know: JSON numbers are a single type backed by IEEE 754 doubles, so an integer like 9007199254740993 (253+1) loses precision the moment JSON.parse reads it — both 9007199254740992 and 9007199254740993 round to the same double. The tool can only type such a field as number; if your API sends 64-bit IDs, keep them as strings in the JSON.
"unknownis the type-safe counterpart ofany. Anything is assignable tounknown, butunknownisn't assignable to anything but itself andanywithout a type assertion or control-flow-based narrowing."— TypeScript 3.0 release notes
That is why an empty array generates unknown[] rather than any[]: with no element to inspect, unknown keeps the value type-checked until you replace it with the real element type. For deeper background on the format itself, read the JSON validation & formatting guide or the JSON vs YAML vs XML comparison.
Worked examples: JSON → TypeScript
Nested object · one interface per object
{ "user": { "id": 7, "name": "Ada" } } → export interface RootObject { user: User; } export interface User { id: number; name: string; }
Mixed array · union type (Array Unions on)
{ "values": [1, "two", true] } → export interface RootObject { values: (number | string | boolean)[]; }
Non-identifier key · quoted property
{ "first-name": "Ada", "user.id": 7 } → export interface RootObject { "first-name": string; "user.id": number; }
Edge case · the null trap
{ "email": null } → email?: null
A field that is null in the sample becomes optional (email?: null) — not email: string | null. One sample can't reveal the real nullable type, so always widen it by hand: change email?: null to email: string | null. Optional ?: means "may be absent", which is a different contract from "present but null".
JSON to TypeScript type-mapping reference
Exact mappings this tool applies, straight from its inference logic. Use it to predict the output before you paste.
| JSON value | Inferred TypeScript | Notes |
|---|---|---|
| "hello" | string | Literal types not inferred — narrow to a union by hand |
| 42, 3.14 | number | JSON has one numeric type; ints and floats both map to number |
| true, false | boolean | Maps directly |
| null | field?: null | Marked optional; widen to T | null after review |
| { ... } | Named interface | One interface per object; PascalCase name, deduped (User2) |
| [1, 2] | number[] | Homogeneous array; element name auto-singularized |
| [1, "a"] | (number | string)[] | Union when Array Unions is on; first type only when off |
| [ ] | unknown[] | No element to infer; type-safe top type, not any[] |
The edge cases most generators get wrong
Two behaviors set this generator apart. First, identifier sanitizing: a JSON object named after a reserved word becomes a safe interface name — a key called interface or class yields an interface named Interface_, and a name that starts with a digit (1stPlace) gets a leading underscore (_1stPlace). Output that would not compile is silently fixed.
Second, root-type handling: when the top-level JSON is a primitive or array rather than an object, the tool emits a type alias instead of an interface — ["a","b"] becomes type RootObject = string[], regardless of whether you picked the interface style. You can't write interface Foo = string[] in TypeScript, so the tool quietly does the correct thing. Array element names are also auto-singularized (categories → Category), so nested interfaces read naturally.
Related developer & data tools
Validate & pretty-print the source payload first
JSON Schema GeneratorRuntime validation alongside your TS types
JSON DiffCompare two payloads to spot shape changes
JSON ↔ YAML ConverterSwitch between JSON and YAML configs
CSV ↔ JSON ConverterTurn tabular data into JSON to type
YAML ValidatorValidate YAML before converting to JSON
XML FormatterTidy and indent XML documents
SQL FormatterFormat queries that return this JSON
Base64 EncoderDecode Base64-wrapped JSON payloads
All ToolsBrowse the full Toolk utility hub
Guide: JSON ValidationRead the JSON validation & formatting guide
Guide: JSON vs YAML vs XMLCompare the three data formats
Last updated: September 15, 2026 · Runs 100% in your browser — no uploads, tool input is not sent to Toolk.
Frequently asked questions
Why is my null-valued field optional instead of nullable?
A single sample cannot reveal a field’s true nullable type, so a null value becomes field?: null. Widen it by hand to something like string | null — the optional ?: marker means “may be absent”, which is a different contract from “present but sometimes null”.
Should I emit interface or type aliases?
For plain object shapes they type-check identically, so follow your team’s convention. Interfaces suit object contracts and declaration merging; type aliases are required anyway when the JSON root is a primitive or an array, and this generator falls back to them automatically in those cases.
How are nested objects and arrays translated?
Nested objects become their own named interfaces with readable names derived from the parent key, arrays become typed arrays of the element interface or union, and enums of literal strings can collapse to union types. The output is plain TypeScript with zero runtime dependencies.
Do API responses with real customer data get uploaded?
No. Generation runs entirely in your browser tab, and Toolk’s page analytics do not receive the JSON you paste. Responses carrying auth tokens, PII, or billing details never leave your device, and conversion keeps working offline once the page has loaded.
What workflow keeps generated interfaces in sync?
Regenerate from a fresh response whenever the endpoint changes rather than hand-editing. Pairing with Toolk’s JSON Schema Generator (/tools/json-schema-generator) gives you a validation layer that catches drift before your types do.