ToolNimba

๐Ÿงฉ JSON to TypeScript Interface Generator

Shihab Mia By Shihab Mia ยท Updated 2026-08-04

TypeScript output
 

Paste JSON above, then press Generate interfaces.

Paste a JSON object or array and this tool generates the matching TypeScript interfaces for you. It walks the data, infers each field type (string, number, boolean, null), turns nested objects into their own named interfaces, and maps arrays to T[]. You set the root interface name, choose whether to export, and copy the result straight into your project. Everything runs in your browser, so your JSON never leaves the page.

What is the JSON to TypeScript?

TypeScript needs to know the shape of your data to give you autocompletion and compile-time safety, but writing interfaces by hand from a sample API response is tedious and error prone. This generator does it mechanically: it parses your JSON, then for every key it reads the value and emits the corresponding TypeScript type. A text value becomes string, a number becomes number, true or false becomes boolean, and null becomes null (or an optional field if you turn that option on).

Nested structures are where hand-writing gets painful, and where the tool earns its keep. When a property holds another object, the generator creates a separate named interface for it (derived from the property name in PascalCase) and references that interface by name, so you get a clean, flat set of declarations rather than one deeply nested blob. The root interface is always printed first, with the interfaces it references following after, which is fine in TypeScript since interface declarations do not need to appear before the code that uses them. Arrays are inferred to an element type and written as ElementType[]. When an array holds objects, their shapes are merged into one shared interface, and any key that is missing from some elements is marked optional with a question mark.

Not every array is that tidy. If an array mixes types, for example numbers and strings in the same list, or objects mixed with plain values, the generator cannot merge them into one shape. Instead it lists every distinct type it found and joins them into a union, written as (string | number)[]. The same logic applies at the very top of your JSON: if the root value you paste is a bare primitive like a number or string, or a top-level array, TypeScript will not let that be an interface, so the tool emits a type alias instead, such as type Root = string[]. Interfaces and type aliases both describe object shapes in TypeScript, but only a type alias can name a union, a primitive, or a tuple directly, which is why the generator switches between the two depending on what sits at the root of your data.

Keep in mind that JSON is only a sample, not a schema. The generator can only describe the exact data you paste: it cannot know that a field is sometimes null, that a number is really an enum, or that an empty array would normally hold strings. It also cannot tell that an ISO date string like 2026-01-01T00:00:00Z represents a date rather than free text, so it types it as string, exactly as written, and it is up to you to parse that string into a Date where your code needs one. Treat the output as a strong first draft. Review the inferred types, widen any that are too specific, add unions or optional markers the sample did not reveal, and rename the auto-generated interfaces to match your domain language.

This approach trades completeness for speed. A single JSON sample, converted client side in your browser, gets you from a raw API response to compiling TypeScript in seconds without installing anything. Command line tools such as quicktype go further: they can merge several samples at once, target other languages besides TypeScript, and emit JSON Schema or runtime validators like Zod alongside the types. For a quick interface while you are wiring up a fetch call or reading through an unfamiliar payload, this generator is usually the faster path; reach for a heavier tool once you need to validate that data at runtime, not just describe its shape at compile time.

When to use it

  • Turning a sample REST or GraphQL API response into typed interfaces before you write the client code.
  • Bootstrapping types for a config file, fixture, or mock data object you already have as JSON.
  • Generating request and response types for a fetch or axios call so a mismatched API field shows up as a compile error, not a runtime bug.
  • Migrating a JavaScript project to TypeScript by generating starting interfaces from runtime data.
  • Quickly checking the shape of an unfamiliar JSON payload by reading its generated structure.
  • Documenting a webhook payload or third-party API response for teammates without writing the types out by hand.

How to use the JSON to TypeScript

  1. Paste your JSON object or array into the input box (it must be valid JSON, with double-quoted keys), or press Load sample to try one.
  2. Type a name for the root interface, for example User or ApiResponse.
  3. Tick Mark null fields optional if you want null values written as an optional property, and toggle Add export keyword to match your project convention.
  4. Press Generate interfaces, review the output for any interface names you want to rename, then copy the TypeScript into your project.

Formula & method

string value to string, number to number, true or false to boolean, null to null, nested object to its own named interface, and a uniform array of objects to ElementType[]. A mixed-type array becomes a union such as (string | number)[]. Keys missing from some elements of an array of objects get a trailing ? to mark them optional. A JSON root that is a bare primitive or a top-level array produces a type alias instead of an interface.
JSON{"id": 1,"name": "Ada","tags": ["math"]}TypeScriptinterface Root {id: number;name: string;tags: string[];}

Worked examples

A flat object: { "id": 1, "name": "Ada", "active": true }, root name User.

  1. id holds a number, so id: number
  2. name holds a string, so name: string
  3. active holds true, so active: boolean
  4. Wrap the three properties in interface User { ... }

Result: export interface User { id: number; name: string; active: boolean; }

A nested object: { "user": { "city": "London" } }, root name Data.

  1. Data is registered first as the root interface
  2. user holds an object, so it becomes its own interface named User
  3. Inside User, city holds a string, so city: string
  4. Emit Data first referencing User, then the User interface

Result: export interface Data { user: User; } export interface User { city: string; }

An array of objects with a missing key: [ { "x": 1, "y": 2 }, { "x": 3 } ], root Point.

  1. Both elements are objects, so their shapes merge into one interface
  2. x appears in every element, so x: number
  3. y appears in only one element, so it becomes optional: y?: number
  4. The element interface is named PointItem, and Point aliases PointItem[]

Result: export interface PointItem { x: number; y?: number; } export type Point = PointItem[];

A property holding mixed types: { "values": [1, "two", true] }, root name Data.

  1. 1 is a number, "two" is a string, and true is a boolean
  2. The array is not all objects, so the shapes cannot merge into one interface
  3. The three distinct types are joined into a union in the order they appear
  4. The property is written as values: (number | string | boolean)[]

Result: export interface Data { values: (number | string | boolean)[]; }

A top-level array of strings: [ "red", "green", "blue" ], root name Color.

  1. The JSON root itself is an array, not an object, so it cannot become an interface
  2. Every element is a string, so the elements merge into a single type: string
  3. No object shape needs a named interface here
  4. The tool emits a type alias instead: type Color = string[]

Result: export type Color = string[];

How JSON values map to inferred TypeScript types

JSON valueInferred TypeScript type
"hello"string
42 or 3.14number
true / falseboolean
nullnull (or optional field if option set)
{ ... }a named interface (PascalCase from the key)
[1, 2, 3]number[]
[1, "two", true]a union type: (number | string | boolean)[]
[ {...}, {...} ]a merged interface, written as Name[]
[] (empty)any[]

Generator options and what they do

OptionEffect
Root interface nameNames the top-level interface or type alias.
Mark null fields optionalRenders a null property as name?: null instead of required.
Add export keywordPrefixes each interface or type alias with export for module use.

interface vs type alias, and what this tool emits

Aspectinterfacetype alias
Can describe an object shapeYesYes
Can describe a union, primitive, or tupleNoYes
Can be extended later with extends or reopened by declaring it againYesNo, use & instead
What this generator outputsEvery object shape it findsOnly a root primitive or a root-level array

Common mistakes to avoid

  • Trusting a single sample as the full schema. JSON shows one snapshot of the data. A field that happens to be filled in your sample might be null or missing in real responses. Review the output and add optional markers or unions the sample did not reveal.
  • Pasting JavaScript object literals instead of JSON. The input must be strict JSON: keys in double quotes, no trailing commas, no comments, and no unquoted identifiers. If you copy a JS object you may need to quote the keys first, or the parse will fail.
  • Expecting literal or enum types automatically. A value of "active" becomes string, not the literal "active". The tool cannot guess that a field is one of a fixed set, so narrow strings to union literal types yourself where it matters.
  • Leaving auto-generated nested interface names as-is. Names are derived from property keys, so deeply nested or repeated keys can produce generic or numbered names. Rename them to meaningful domain terms before committing the types.
  • Expecting a mixed array to merge into one interface. If an array holds a mix of primitives, or objects mixed with non-objects, the tool cannot merge those shapes and instead outputs a union such as (string | number)[]. If you expected one consistent object shape, check your sample for an element that does not match the rest.
  • Forgetting that date strings stay as string. JSON has no date type, so an ISO timestamp like "2026-01-01T00:00:00Z" is always typed as string, never as Date. If your code parses that field into a Date object, add that type by hand after copying the output.

Glossary

Interface
A TypeScript construct that describes the shape of an object: which properties it has and their types.
Type alias
A declaration written as type Name = ... that can point to an object shape, a union, a primitive, or a tuple, unlike interface, which only describes object shapes.
Type inference
Working out a type automatically from a value, rather than writing it out by hand.
Optional property
A property marked with ? that may be present or absent on an object without a type error.
Union type
A type that allows one of several alternatives, written with the pipe symbol, such as string or number.
PascalCase
A naming style where each word starts with a capital letter and there are no separators, used here for interface names.
Declaration merging
A TypeScript feature unique to interfaces, where declaring the same interface name twice adds to it rather than replacing it. This generator gives every interface a unique name, so merging never happens in its output.
Ambient declaration file
A .d.ts file that holds only type information and no runtime code, a common place to paste generated interfaces that several files in a project need to share.

Frequently asked questions

How do I convert JSON to a TypeScript interface?

Paste your JSON into the input box, give the root interface a name, and press Generate interfaces. The tool reads each field, infers its type, turns nested objects into their own interfaces, and outputs ready-to-copy TypeScript.

Does it handle nested objects and arrays?

Yes. Each nested object becomes its own named interface referenced by the parent. Arrays are written as ElementType[], and an array of objects has its element shapes merged into a single shared interface.

What happens with null values?

By default a null value is typed as null. If you tick the option to mark null fields optional, that property is rendered with a question mark instead, which is often what you want for fields that may be absent.

Why are some fields marked optional with a question mark?

When you give an array of objects, the generator merges their shapes. Any key that appears in some elements but not all is marked optional, since it is not guaranteed to be present on every object.

Is my JSON sent anywhere?

No. The whole conversion runs in your browser using the built-in JSON parser. Nothing is uploaded, logged, or sent over the network, so it is safe to paste private or internal data.

Why did I get an Invalid JSON error?

The input must be strict JSON: property names in double quotes, no trailing commas, no comments, and no single quotes. The error message shows where parsing failed so you can fix that spot and try again.

Can it output type instead of interface?

The tool always emits interface for an object shape. It only switches to a type alias when the root of your JSON is a bare primitive or a top-level array, since TypeScript requires those to be written that way. If your project prefers type everywhere, you can safely change the keyword yourself after copying, since a plain object shape works with either.

Why did I get a union type like (string | number)[]?

An array that mixes different primitive types, or mixes objects with non-objects, cannot be merged into one shape. The generator instead lists every distinct type it found in that array and joins them with a pipe. If you expected one consistent shape, check your sample for an element that does not match the rest.

Does it detect date strings and convert them to Date?

No. JSON has no date type, so an ISO date string such as 2026-01-01T00:00:00Z is always inferred as string, exactly as it appears in the payload. If your code parses that field into a JavaScript Date object, add that type by hand, since the tool cannot infer intent from a string format alone.

How is this different from quicktype or a code editor extension?

The underlying idea is the same: infer types from a JSON sample. This tool is a fast, no-install way to do that from one sample directly in the browser, kept intentionally simple with just root naming, optional-null, and export toggles. Command line tools such as quicktype can merge multiple samples, target other languages, and generate JSON Schema or runtime validators, which is worth reaching for on a larger codebase.