JSON -> TypeScript

Paste JSON - get typed interfaces. All processing in the browser.

INPUT · JSON
OUTPUT · TypeScript
Output will appear here after conversion.

Technical SEO

Expanded documentation

JSON to TypeScript: Stop Writing Interfaces by Hand

Every frontend engineer has been there: a backend colleague pastes a 300-line JSON response into Slack and says "type this." You open your editor, start mapping string, number, and boolean by hand, and twenty minutes later you have a brittle interface that will drift the moment the API evolves. There is a better way — and it starts here.

What Problem Does This Tool Solve?

REST and GraphQL APIs return JSON. TypeScript applications need typed interfaces. Bridging that gap manually is error-prone and expensive:

  • Nested objects require recursive interface definitions that are tedious to trace by eye.
  • Optional vs required fields depend on domain knowledge the JSON sample may not convey.
  • Union types (string | null, number | string) appear in dynamic APIs but are invisible in a naive typeof pass.
  • Array inference — knowing whether items: [] should be items: unknown[] or items: Product[] — requires reading the surrounding structure, not just the key name.

The JSON to TypeScript online converter handles all of this in milliseconds, entirely in the browser. No data leaves your machine.

How the Conversion Algorithm Works

The converter performs a single-pass recursive descent over the parsed JSON AST:

  1. Primitive detectiontypeof value maps string, number, boolean, null, and undefined to their TypeScript equivalents. null is emitted as null rather than any to preserve nullability semantics.
  2. Object materialisation — Each key-value pair becomes an interface property. Keys are sanitised (spaces and hyphens become camelCase, numeric-only keys gain an underscore prefix) to produce valid TypeScript identifiers.
  3. Array homogeneity check — If every element in an array shares the same resolved type, the output is ElementType[]. If elements are mixed (e.g., [1, "two", null]), a union type (number | string | null)[] is generated.
  4. Recursive interface extraction — Nested objects are promoted to named child interfaces and referenced by name, keeping the root interface shallow and readable. The naming heuristic capitalises the property key: a key userProfile produces interface UserProfile { … }.
  5. Duplicate deduplication — If two sibling properties resolve to structurally identical interfaces, only one definition is emitted and both properties reference it.

The result is idiomatic TypeScript — not a one-liner type Foo = Record<string, unknown>, but properly annotated, deeply nested, named interfaces your IDE can navigate.

Step-by-Step Usage Guide

Step 1 — Paste your JSON Copy the raw JSON from your API explorer, Postman response, or browser Network tab and paste it into the left panel. The converter accepts any valid JSON, including arrays at the root level ([{ … }, { … }]).

Step 2 — Review the output The right panel updates in real time. Each interface is named after the key that produced it, with the root interface called Root. Scan for any types — they indicate keys the converter could not infer (e.g., an empty array []). You may want to annotate those manually once you know the element type.

Step 3 — Rename and adjust Copy the output and rename Root to match your domain model (ApiResponse, UserProfile, CartItem). Add export keywords where needed. Consider moving nested interfaces to a shared types/ file.

Step 4 — Validate with tsc Run tsc --noEmit against a file that imports your new types. TypeScript will surface any mismatches between your interface and the actual usage.

Engineering Concepts: TypeScript's Structural Type System

TypeScript uses a structural (duck-typed) type system rather than a nominal one. This means that two interfaces with identical shapes are assignable to each other even without an extends relationship. This has a direct consequence for generated interfaces: the output does not need to mirror your class hierarchy — it only needs to correctly describe the shape.

When working with API types, it is common to generate interfaces and then narrow them at runtime with type guards:

function isUser(value: unknown): value is User {
  return (
    typeof value === 'object' &&
    value !== null &&
    typeof (value as User).id === 'number'
  );
}

Type guards bridge the gap between unknown (the safe type for unvalidated API data) and your generated interface. Libraries like zod and io-ts take this further by deriving both the runtime validator and the TypeScript type from a single schema definition.

Best Practices for Generated TypeScript Interfaces

Mark optional fields explicitly. If an API field is sometimes absent, add ? to the property:

interface Product {
  id: number;
  discountCode?: string; // absent for full-price items
}

Prefer unknown over any for dynamic payloads. Unlike any, unknown forces a type check before use:

const raw: unknown = JSON.parse(responseText);
const data = raw as ApiResponse; // explicit cast, auditable

Namespace your generated types. Group API response interfaces in a namespace or a dedicated file (api.d.ts) to prevent name collisions with your domain model.

Regenerate on schema change, not on every deploy. Generated interfaces are source artifacts — commit them to version control and regenerate them only when the API contract changes, not on every CI run. This gives you a meaningful diff when APIs evolve.

Version your interfaces. When an API ships a breaking change, add a version suffix (UserV2) and maintain both until all consumers are migrated.

Comparison: Manual vs. Tool-Assisted Typing

ApproachTime for 50-field responseError rateHandles nesting
Manual25–40 minHigh (typos, missed nulls)Tedious
IDE plugin (Paste JSON as Code)~30 secLowYes
This online formatterInstantLowYes
zod schema derivationRequires schemaVery lowYes

The online developer utility wins on speed and zero-setup. It is the right tool for one-off conversions, onboarding new API endpoints, and exploratory typing. For production systems with strict validation requirements, pair the generated interfaces with a schema-validation library.

Common Pitfalls to Avoid

  • Trusting a single sample. A JSON sample is a snapshot. Run the converter against multiple response variations to catch fields that appear only under certain conditions.
  • Ignoring date strings. JSON has no date type. The converter emits string for ISO timestamps. Alias them: type ISODateString = string and use that alias for clarity.
  • Forgetting discriminated unions. If your API returns { type: "order", … } | { type: "invoice", … }, the converter will produce a merged interface. Refactor the output into a proper discriminated union for exhaustive pattern matching.

This developer utility removes the mechanical work so you can focus on the semantic work — understanding what the data means, not transcribing its shape.