JSON to TypeScript
Generate TypeScript interfaces (or type aliases, or Zod schemas) from a JSON sample.
Handles nested objects, mixed-type arrays, nullable fields, optional fields, and ISO date detection.
Runs entirely in your browser. Useful for typing an API response, locking in a config shape, or
scaffolding model definitions from a sample payload.
How to use the JSON to TypeScript tool
Paste a JSON sample, name the root type, click Convert. The output panel shows a valid TypeScript file with the inferred types. Copy it into your codebase and you're typed.
For best results, paste a JSON sample that's representative of the data you actually receive — not just the happy path. If a field is sometimes null and sometimes a string, include both in an array sample so the tool unions them correctly. If a field is sometimes absent, include records both with and without the field so optionality is captured.
When the output format is Zod schema, you get parse-able runtime validators. Use
them at API boundaries: parse incoming data, get typed values out, throw on mismatch. This is more
robust than trusting JSON.parse + a cast.
How the inference works
The tool walks the JSON tree depth-first. For each value it determines a base type
(string, number, boolean, null, object, or
array). Objects become interfaces named by key path. Arrays of primitives become
T[]; arrays of objects become arrays of generated interfaces, with shape merging if
the option is on.
Optionality is determined by comparing object shapes across array elements: if a key appears in 8
out of 10 elements, it's marked ?: (optional). Nullability is determined by whether
any value at that path is null.
Date detection runs a regex (^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}) against string
values. Matches keep string as the type but get a JSDoc comment hinting at the format,
because TypeScript has no native Date distinct from string in JSON.
Where this is useful
- API client scaffolding. You hit a new third-party API, capture the response, paste it, get a starting set of types.
- Backend payload typing. A webhook delivers JSON; you want to type the parsed body without writing the schema by hand.
- Config file shape. Your app reads a JSON config; paste the sample to get a type that catches typos at compile time.
- LLM output structure. When you constrain an LLM to a specific JSON shape, paste an example output to get the type that
JSON.parsewould yield. - Mock data typing. A test fixture is a JSON literal; matching its type to the production type catches drift.
Limits and caveats
Type inference from JSON is structural — it captures what's in the sample, not what's possible.
A field that's always "active" in your sample will be typed as the string literal
"active", even though the API might return any string. The tool widens single-value
primitives to base types (string not "active") unless the "Preserve literal
types" option is on (off by default for this reason).
Discriminated unions are not auto-detected. If your API returns objects with a type
field that determines the rest of the shape, you'll get a structural union, not a tagged union.
Refine the generated types by hand for that pattern.
Numbers are typed as number. JSON does not distinguish integers from floats; if you
need bigint for very large IDs, edit the generated type.
Frequently asked questions
How does the tool handle arrays where elements have different shapes?
[{"a":1}, {"b":2}] becomes Array<{ a?: number } | { b?: number }> by default. If the "Merge similar shapes" option is on, the tool detects when shapes mostly overlap and produces { a?: number; b?: number } instead, which is what you usually want.What about nullable fields?
null in the input, the generated type is null. When a field is present in some array elements but missing in others, the field is marked optional with ?. When a field appears as both null and a value across different inputs, the type becomes T | null.Does it generate types or interfaces?
interface because they're extendable and play better with IDE tooltips. Switch to type aliases if you prefer or if you need union/intersection composition. Both produce valid TypeScript; pick what matches your codebase style.Can it generate Zod schemas?
z.object, z.array, z.string, z.number, z.boolean, z.null, z.union. Optional fields use .optional().How do I name the root interface?
Root; change it to whatever matches your domain (e.g., ApiResponse, User). Nested object types are auto-named based on the key path (e.g., a user.address object becomes UserAddress).Does it handle date strings?
2026-05-28T12:34:56Z) are detected and typed as string by default with a comment noting the ISO format. Toggle "Detect date strings" off if you want pure structural inference.