Skip to main content

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

  1. Paste valid JSON into the input — an API response, a config blob, or a sample payload. The output updates instantly.
  2. Set a meaningful Root Name (for example StripePaymentIntent) so the top-level type reads well.
  3. Choose interface or type as the declaration style to match your team's lint config.
  4. Toggle export, semicolons, and Array Unions to fit your code style.
  5. 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.

"unknown is the type-safe counterpart of any. Anything is assignable to unknown, but unknown isn't assignable to anything but itself and any without 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 valueInferred TypeScriptNotes
"hello"stringLiteral types not inferred — narrow to a union by hand
42, 3.14numberJSON has one numeric type; ints and floats both map to number
true, falsebooleanMaps directly
nullfield?: nullMarked optional; widen to T | null after review
{ ... }Named interfaceOne 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 (categoriesCategory), so nested interfaces read naturally.

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.

Need a different tool?

Browse all 103 browser-based tools (103 currently marked free), or tell us what useful utility we should build next.

Browse all tools