Tools Guides
developer Free No signup

JSON to TypeScript Interface Generator

Convert JSON objects into TypeScript interface or type alias definitions automatically.

Loading tool…

About this tool

Paste any JSON and instantly generate TypeScript interfaces with proper types, nested interfaces, optional fields, and array types. Supports options for interface vs type alias, JSDoc comments, and readonly modifiers to match your project's coding style.

How to use

  1. 1 Step 1: Paste your JSON object into the input area.
  2. 2 Step 2: Enter a root interface name (defaults to 'Root').
  3. 3 Step 3: Toggle options for type alias, JSDoc comments, or readonly modifier.
  4. 4 Step 4: Click Generate and copy the TypeScript output.

Turning a JSON sample into typed interfaces

When you consume an API or read a config file, the JSON arrives as plain text with no guarantees about shape. TypeScript can't help you until that shape is described as an interface or type. Writing those declarations by hand is tedious and error-prone — one mistyped field name and the compiler quietly lets a bug through. This tool reads a real JSON sample and infers the type of every field for you, walking the object recursively and producing a complete set of interfaces. Everything runs in your browser with JSON.parse, so the data you paste never leaves your machine.

How the type inference works

The generator looks at the JavaScript type of each value and maps it to a TypeScript type. A string becomes string, a number becomes number, a boolean becomes boolean. When it meets a nested object, it gives that object its own interface and names it by PascalCasing the key — so a field called shipping_address produces an interface named ShippingAddress and the parent field is typed as that interface. Arrays are inspected element by element: the tool collects the distinct types it finds and builds a union. An array of numbers becomes number[]; a mixed array becomes something like (string | number)[]; an empty array, having nothing to inspect, falls back to unknown[].

Two cases deserve attention. A null value can't reveal its real type, so the field is typed as unknown and marked optional with a ? — a deliberately conservative choice that forces you to narrow it before use. And duplicate nested interfaces are de-duplicated: if the same shape name appears twice, it is only emitted once.

A worked example

Paste this object with the root name left as Root:

  • { "name": "Alice", "age": 30, "address": { "city": "Seoul", "zip": null }, "tags": ["dev", "design"] }

The tool emits the nested interface first, then the root last, so dependencies are declared before they are used:

  • interface Address { city: string; zip?: unknown; }
  • interface Root { name: string; age: number; address: Address; tags: string[]; }

Notice that zip became optional and unknown because its sample value was null, and tags collapsed to a clean string[] because every element was a string.

The options, and when to use them

  • Use type alias. Switches the keyword from interface Foo { to type Foo = {. Interfaces are usually preferred for object shapes because they support declaration merging and tend to give clearer error messages; reach for type when you plan to build unions or intersections on top of the shape.
  • readonly modifier. Prefixes every property with readonly, which is ideal for data you fetch and never mutate — the compiler then stops accidental reassignment of fields on an API response.
  • JSDoc comments. Adds a /** key */ line above each property, a useful scaffold when you intend to document the meaning of fields by hand afterwards.
  • Root Interface Name. Rename Root to something meaningful like UserProfile so the generated top-level type reads naturally in your code.

Common pitfalls this exposes

  • A sample is not a schema. The output describes the exact JSON you pasted, not every response the API can send. If a field is sometimes absent or sometimes null, capture a sample that includes those cases, or widen the type by hand afterwards (for example to string | null).
  • Top level must be an object. The generator needs a wrapping { } to build a named interface. If your data is a bare array like [ … ], wrap one representative element in an object first, generate its interface, then type the whole payload as Element[].
  • Optional vs. nullable. A property here is only marked optional when its sample value is null. A field that is genuinely absent in some responses won't be caught from a single complete sample — review the result against the API docs.
  • Integers and floats are both number. TypeScript has no integer type, so 30 and 3.14 both map to number. Don't expect a narrower numeric type.

Where it fits in your workflow

The fastest way to add types to an untyped fetch is to copy one real response from your network tab, paste it here, name the root after the endpoint, and drop the generated interfaces into a types.ts file. From there you annotate your fetch call's return type and let the compiler guide the rest. It is also handy for typing fixtures in tests, describing the shape of a settings file, or onboarding a teammate who needs to see an API's structure at a glance. Treat the output as a strong first draft — accurate for the sample, and a quick foundation you refine for the full range of real data.

Frequently Asked Questions

{# Alpine.js — self-hosted. (The previous jsdelivr CDN tag had a stale SRI integrity hash, so the browser refused to run it and window.Alpine was never defined — silently breaking every FAQ accordion and Alpine tool.) #}