Skip to main content

JSON to TypeScript

Paste JSON and get TypeScript interfaces or type aliases, with nested objects extracted into their own named types and array element types inferred.

Turn a JSON sample into TypeScript type declarations. Nested objects are extracted into their own named types rather than being inlined, and you can choose between interfaces and type aliases and set the name of the root type.

JSON to TypeScript
Root name
Mode
Paste some JSON...

// JSON to TypeScript: Features

Interfaces or type aliases

Both modes describe the same shapes and the choice is largely stylistic. Interfaces support declaration merging and extend clauses, produce slightly friendlier error messages in some editors, and are the conventional choice for object shapes. Type aliases compose more flexibly with unions, intersections and mapped types, and many codebases now use them uniformly for consistency. Pick whichever matches the code you are pasting into.

Nested objects get their own names

A deeply nested response inlined into one enormous type is unreadable and impossible to reference. The generator extracts each nested object into its own named declaration derived from the key it appeared under, so a user object inside a response becomes a separate type you can import and reuse. Setting the root name controls the top of that hierarchy and therefore the naming of everything beneath it.

What an example cannot tell you

The same limitation applies here as to any inference from a sample. A field present in the example is typed as required, even if the API omits it sometimes. A field containing null is typed from that null, not as a nullable version of its real type. An empty array gives no element type. A string that is really an enum of three values is typed as string. The generated output is a fast and accurate starting point, not a contract; review optionality and nullability before relying on it.

Numbers, dates and identifiers

JSON has one numeric type, so TypeScript gets number, and an integer identifier beyond the safe range will already have lost precision before the generator sees it. Dates arrive as strings, because JSON has no date type, so a field holding an ISO timestamp is typed as string; whether to narrow that to a branded type or convert at the boundary is a decision for your codebase. Identifiers that are numeric strings stay strings, which is usually what you want.

Why a real API response makes better types

Generation runs as JavaScript in your browser, so a real API response containing customer data can be used as the sample without being transmitted, stored or logged. Using a real response matters: it produces types that match what the service actually returns, including fields you might not have thought to include. To describe the same document as a validation schema instead, the JSON Schema generator is available in the Japanese edition.

// JSON to TypeScript: FAQ

What does it generate?

TypeScript type declarations describing the JSON you paste, either as interfaces or as type aliases. Nested objects become separate named types rather than being inlined, and the counts underneath tell you how many types and properties were produced.

Should I choose interface or type?

Either works for describing object shapes. Interfaces allow declaration merging and extend clauses and are the traditional choice; type aliases compose better with unions and other type-level operations and are increasingly used uniformly. Match whatever convention the codebase you are pasting into already follows.

Are optional fields detected?

No. Every property present in the sample is generated as required, because a single example cannot show that a field is sometimes absent. Mark the genuinely optional ones with a question mark by hand, based on the API contract rather than on one response.

How are null values typed?

A field containing null in the sample is typed from that null, which is almost never what you want long-term. Where a field is nullable, widen it to a union with the real type. This is the single most common edit people make to generated types.

What happens with arrays?

The element type is inferred from the items present. A uniform array of objects produces a clean array type referencing a named element type. An empty array has no elements to infer from, and an array with mixed types produces something you will want to tighten, often into a discriminated union.

Are dates typed as Date?

No, they are typed as string, because that is what JSON actually contains. JSON has no date type, so a timestamp arrives as an ISO string and is faithfully typed as one. Converting to Date objects is a decision for the boundary of your application, where you parse the response.

Can it produce a union type from an enum-like field?

Not from a single sample, because one value cannot reveal the set of permitted values. A status field containing the string active is typed as string. If you know the full set, narrowing it to a union of string literals afterwards is one of the highest-value edits you can make, because it turns a whole class of typos into compile errors.

How does it name the generated types?

From the key each nested object appeared under, with the root type taking the name you supply. Setting a meaningful root name is worthwhile because it propagates: a root called UserResponse produces more readable nested names than one left at a generic default.

Is it safe to paste a real API response?

Yes. Everything runs in your browser and the document is never transmitted, stored or logged. Using a real response is recommended, because a hand-written example tends to omit exactly the fields that cause type errors later.

Is the API response I paste sent to a server?

No. Generation happens entirely in the page, and closing the tab discards whatever you pasted.

// How to Use JSON to TypeScript

  1. Paste a representative response

    Put a real JSON document into the input box. The fullest example you have produces the most useful types, because fields missing from the sample are missing from the output.

  2. Set the root name and mode

    Give the root type a meaningful name, since nested type names derive from it, and choose whether to emit interfaces or type aliases to match your codebase.

  3. Copy and tighten

    Copy the declarations, then make the edits an example cannot infer: mark optional fields with a question mark, widen nullable fields to a union, and narrow enum-like strings to string literal unions.

Category Data Formats