JSON to TypeScript Interface

Walks a JSON sample's shape and emits TypeScript interface declarations, with nested objects hoisted into their own named interfaces derived from the parent key, nullable unions, and optional fields for inconsistent array items. A free online tool from Staaarter, right in your browser.

Runs locallyUpdated 2026-07-26

Overview

Introduction

Hand-writing a TypeScript interface for a JSON payload works fine for a handful of flat fields, but gets tedious and error-prone fast once nested objects and arrays of records enter the picture. This tool walks a real JSON sample and generates the interface declarations for you, nested objects included.

It's one of four sibling generators on this site (TypeScript, Python, Go, Zod) that all infer a JSON value's shape the same consistent way and differ only in how that shape is rendered as target-language code.

What Is JSON to TypeScript Interface?

A generator that infers TypeScript types from a JSON sample and emits `interface` declarations: primitives map to `string`/`number`/`boolean`/`null`, arrays map to `T[]`, and nested objects are hoisted into their own named interface, derived from the parent's name plus the key (`RootObject` -> `RootObjectAddress` for a nested `address` field), rather than being inlined.

When the input is an array of objects, their shapes are merged: a key present in every element is required, a key present in only some becomes optional (`?`), and a key observed as `null` in at least one element gets its type unioned with `null`.

The output is plain TypeScript text; nothing is compiled, type-checked, or executed, this tool only emits source you paste into your own project.

How JSON to TypeScript Interface Works

The generator parses your JSON, then walks it recursively via a shared shape-inference step (also used by this site's Python dataclass, Go struct, and Zod schema generators) that classifies every value as a string, integer, float, boolean, null, unknown (for an empty array's element type), an array, or an object with named fields.

Rendering that shape as TypeScript hoists every object shape it encounters into a separate named `interface` declaration (reserving a unique name, appending a numeric suffix on a naming collision), and emits the root value's declarations last, either the root interface itself, or, when the root isn't an object, a `type RootObject = ...;` alias to whatever the root's inferred type turned out to be.

When To Use JSON to TypeScript Interface

Use it right after capturing a real API response, config file, or webhook payload, when you want compile-time types for that shape without hand-transcribing every field and nested object.

It's also useful for quickly sanity-checking how many distinct nested shapes a sample actually has. A payload you expected to be flat generating five hoisted interfaces is a fast signal that it's more deeply nested than you thought.

Features

Advantages

  • Hoists nested objects into their own clearly-named interfaces instead of one deeply inlined type, which is easier to read and reuse.
  • Merges shapes across an array of objects to correctly infer optional fields and nullable unions, not just the first element's shape.
  • Quotes JSON keys that aren't valid TypeScript identifiers instead of silently mangling or dropping them.
  • Shares its shape-inference behavior with this site's Python, Go, and Zod generators, so the same JSON sample produces consistent field-level decisions (nullability, optionality) across all four output languages.

Limitations

  • Inferred purely from the sample you provide; a field that's always a string in your sample but could be a number elsewhere in your real data won't be reflected as a union unless your sample actually shows both.
  • Generated types disappear entirely at compile time and never validate anything at runtime; a malformed API response that doesn't match the generated interface will still be accepted by TypeScript and fail somewhere downstream instead of at the boundary. Use the JSON Schema Generator or JSON to Zod Schema tool if you need an actual runtime check.
  • Arrays with mixed, non-object element types, or arrays mixing objects and primitives, fall back to the first element's inferred type; a genuinely heterogeneous array needs manual review of the output.

Examples

Flat object

Input

{"id":1,"name":"Ada","active":true}

Output

interface RootObject {
  id: number;
  name: string;
  active: boolean;
}

Each key gets its inferred TypeScript type; the interface defaults to the name RootObject.

Nested object hoisted into its own interface

Input

{"address":{"city":"London"}}

Output

interface RootObjectAddress {
  city: string;
}

interface RootObject {
  address: RootObjectAddress;
}

The nested address object gets its own interface named from the parent key, referenced by name from RootObject.

Optional and nullable fields from an array of objects

Input

[{"a":1,"b":2},{"a":3,"b":null}]

Output

interface RootObject {
  a: number;
  b: number | null;
}

b is present in every element (so not optional) but observed as null once, so its type is unioned with null.

Best Practices & Notes

Best Practices

  • Generate from your most complete real sample, since fields absent from every element of your sample can't be inferred at all.
  • Treat the output as a starting point for editor autocomplete and compile-time checks, not as a runtime guarantee; pair it with the JSON to Zod Schema or JSON Schema Generator tool if you need to validate real payloads at runtime.
  • Rename the root interface with the root name option when generating types for a specific named entity (User, Order) rather than leaving every generated file's root type called RootObject.
  • Review any interface with an optional field for whether the field is genuinely optional in your API contract, or just happened to be absent from one element of your specific sample.

Developer Notes

Built on a shared shape-inference module (also used by this site's Python dataclass, Go struct, and Zod schema generators) that classifies every JSON value and, for arrays of objects, merges field presence/nullability across all elements rather than only inspecting the first one. Nested object shapes are hoisted via a name-reservation helper that appends a numeric suffix on a collision (e.g. two sibling keys both PascalCasing to "Item" become Item and Item1); the same helper is used to avoid a name clash when the JSON root itself is an array of objects, since both the hoisted element interface and the root type alias would otherwise want the same name.

JSON to TypeScript Interface Use Cases

  • Generating request/response types for a REST API client from a real captured payload.
  • Typing a config file or environment payload consumed by a TypeScript application.
  • Quickly producing a starting-point interface to refine by hand for a new integration.
  • Documenting a JSON payload's shape for teammates in a form the TypeScript compiler can also check.

Common Mistakes

  • Treating the generated interface as validation; TypeScript types are erased at compile time and never check real data at runtime.
  • Generating from an unrepresentative sample and missing fields, or optionality, that only show up in some real responses.
  • Assuming a mixed-type array produced a proper union; non-object mixed arrays fall back to the first element's type and need manual review.

Tips

  • Pair with the JSON to Zod Schema tool when you need both compile-time types and a runtime check from the same sample.
  • Search the output for interfaces with only one or two fields; they're often a sign a nested object in your source data is smaller and more reusable than expected.
  • If two hoisted interfaces end up with a numeric suffix (Item, Item1), consider renaming one of the source keys for clearer generated names.

References

Frequently Asked Questions