ToolsWhisper
Developer tools

JSON to TypeScript Converter

Generate TypeScript interfaces or types from a JSON sample.

  • Runs in your browser
  • Nothing is uploaded
  • Free, no sign-up
Declare with
JSON
TypeScript

Types are inferred from this one sample. A field that was always present here may be optional in other responses, so check the result against the API's documentation before relying on it.

About this tool

Paste an API response or a config file and get the TypeScript declarations for it: one named interface per nested object, arrays typed by their elements, and unions where the sample disagrees with itself. It reads the JSON locally and nothing is uploaded.

How to use it

  1. Paste a JSON sample into the input pane.
  2. Set the root type name and choose interface or type, with or without export and readonly.
  3. Copy the declarations into your project, or download them as types.ts.

What gets inferred

JSON TypeScript
"text" string
42, 3.14 number
true boolean
null null
["a", "b"] string[]
[] unknown[]
{ "city": "London" } a named interface
{} Record<string, unknown>

An array whose elements disagree becomes a union: [1, "a"] is (number | string)[].

Each nested object gets its own declaration, listed after the type that uses it. Two objects with exactly the same shape share one declaration instead of producing two copies.

Optional properties come from arrays

A single object cannot tell you which of its fields are optional, because every field in it is present. An array can: when elements of an array disagree, a property missing from some of them becomes optional, and a property whose type differs becomes a union.

So the more representative your sample, the better the result. If an endpoint sometimes omits coupon, paste a response containing several orders, at least one with and one without, and the field comes out as coupon?: string.

How names are chosen

A nested object takes its name from the property that holds it, converted to PascalCase: address becomes Address, and first-name becomes FirstName. For an array, the singular is used: orders yields Order, and categories yields Category.

If two different shapes would have the same name, the second is numbered (Item, Item2). Property names that are not valid identifiers, such as "first-name" or "2fa", are quoted.

What a sample cannot tell you

Types inferred from data are a starting point, not a specification:

  • Dates are strings. An ISO timestamp is typed string; model it as a Date after parsing if you need to.
  • Enums are not detected. A field that was always "draft" in the sample is string, not "draft" | "published".
  • A field that is never null in the sample is not nullable here, even if the API can return null.
  • The types disappear at runtime. TypeScript does not check that a response actually has this shape. For data you do not control, validate it with a schema library at the boundary.

For the data itself, the JSON formatter will validate and tidy the sample first.

Frequently asked questions

Should I use interface or type?

For plain object shapes they behave almost identically. Interfaces can be extended and merged, and give slightly clearer error messages; type aliases can express unions and mapped types. Follow your project's convention.

Why is a field typed as a union?

Because the sample used different types for it, for example a number in one array element and a string in another. That is usually worth looking at, since it suggests inconsistent data.

Can it handle very large JSON?

Yes, within what your browser can parse. Arrays are merged element by element, so a long array of similar objects still produces one compact declaration.

Is my JSON uploaded?

No. Parsing and inference happen in your browser, so API responses containing real data stay on your device.

Related tools