JSONShield
typescriptjsonjavascriptdevtools

Generate TypeScript Types from JSON Automatically

Generate TypeScript Types from JSON Automatically

You have a JSON API response. You need TypeScript types for it. Writing them by hand is tedious, error-prone, and something a computer should do for you.

Here are five ways to generate TypeScript types from JSON, from zero-config CLI tools to manual approaches for when the generators get it wrong.

Method 1: quicktype (CLI)

quicktype is the most mature JSON-to-TypeScript tool. It infers types from sample JSON and produces clean, well-named interfaces.

# Install
npm install -g quicktype

From a JSON file

quicktype data.json -o types.ts --lang ts

From a URL (e.g., a REST API endpoint)

quicktype https://api.example.com/users -o types.ts --lang ts

From clipboard (pipe it in)

pbpaste | quicktype --lang ts

Example input:

{
  "id": 1,
  "name": "Alice Johnson",
  "email": "alice@example.com",
  "roles": ["admin", "editor"],
  "profile": {
    "bio": "Software engineer",
    "avatar_url": "https://example.com/alice.jpg",
    "social": {
      "twitter": "@alice",
      "github": "alicej"
    }
  },
  "created_at": "2025-03-15T10:30:00Z"
}

quicktype output:

export interface User {
  id:         number;
  name:       string;
  email:      string;
  roles:      string[];
  profile:    Profile;
  created_at: string;
}

export interface Profile { bio: string; avatar_url: string; social: Social; }

export interface Social { twitter: string; github: string; }

quicktype is smart about naming nested interfaces and handles arrays of objects by inferring a unified type from all elements.

Pro tip: Feed quicktype multiple JSON samples to get more accurate types:

quicktype sample1.json sample2.json sample3.json -o types.ts --lang ts

This helps it distinguish between required and optional fields.

Method 2: json2ts (npm Package)

If you want to generate types programmatically inside a build script or codegen pipeline, json-to-ts works as a library:

npm install json-to-ts

import JsonToTS from 'json-to-ts';

const json = { id: 1, name: "Alice", settings: { theme: "dark", notifications: true } };

const types = JsonToTS(json); types.forEach(t => console.log(t));

Output:

interface RootObject {
  id: number;
  name: string;
  settings: Settings;
}

interface Settings { theme: string; notifications: boolean; }

This is useful for CI pipelines where you want to auto-generate types from API fixtures or OpenAPI response examples.

Method 3: Online Tools

For quick one-off conversions, online tools are the fastest path.

transform.tools/json-to-typescript -- Paste JSON, get TypeScript. Clean UI, runs client-side. This is the community standard for quick conversions.

jsonshield.com -- Has a JSON-to-types converter alongside its other JSON utilities. Useful if you are already using it for formatting or validation.

quicktype.io -- The web version of the quicktype CLI. Supports multiple output languages (TypeScript, Go, Rust, Python, etc.) from a single JSON input.

When using any online tool with production data, verify it processes data client-side. Open DevTools Network tab, paste your JSON, and check that no requests are made to a server.

Method 4: VS Code Extensions

If you live in VS Code, install one of these:

Paste JSON as Code (quicktype) -- Select "Paste JSON as Types" from the command palette. It uses quicktype under the hood and inserts the generated types directly into your editor.

Cmd+Shift+P -> "Paste JSON as Code"

JSON to TS -- Another option that converts JSON from your clipboard to TypeScript interfaces. Simpler than quicktype but handles basic cases well.

Both extensions are free and work offline.

Method 5: Manual Approach for Complex Cases

Automated tools fail on certain patterns. When they do, here is a systematic manual approach:

Union Types

JSON:

{ "status": "active" }
{ "status": "inactive" }
{ "status": "pending" }

Generators will produce status: string. You want:

type Status = "active" | "inactive" | "pending";

interface User { status: Status; }

Discriminated Unions

JSON:

{ "type": "text", "content": "Hello" }
{ "type": "image", "url": "https://...", "width": 800, "height": 600 }

Generators produce one interface with all fields optional. You want:

interface TextBlock {
  type: "text";
  content: string;
}

interface ImageBlock { type: "image"; url: string; width: number; height: number; }

type Block = TextBlock | ImageBlock;

Nullable vs Optional

JSON with null values:

{ "name": "Alice", "nickname": null }

Generators often produce nickname: any. You want:

interface User {
  name: string;
  nickname: string | null;
}

Dates

JSON:

{ "created_at": "2025-03-15T10:30:00Z" }

Every generator will output created_at: string. This is technically correct but you may want a branded type:

type ISODateString = string & { readonly __brand: "ISODateString" };

interface User { created_at: ISODateString; }

The Practical Workflow

Here is what works in practice for most teams:

  1. Start with quicktype to generate a baseline set of types from real API responses.
  2. Review and refine the generated types. Replace string with union types where you know the possible values. Mark truly optional fields with ?.
  3. Store the generated types in your codebase, not in a build artifact. This lets you manually adjust them and keeps them version-controlled.
  4. Re-generate when the API changes. Run quicktype again, diff the output against your existing types, and merge the changes.

For APIs you control, consider generating types from the source of truth (OpenAPI spec, GraphQL schema, or database schema) rather than from JSON samples. Tools like openapi-typescript and GraphQL Code Generator produce more accurate types because they have access to the full schema, not just examples.

Type Generation from OpenAPI

If your API has an OpenAPI spec, skip JSON entirely:

npx openapi-typescript https://api.example.com/openapi.json -o api-types.ts

This produces types for every endpoint, request body, and response. It handles nullable fields, enums, and required vs optional correctly because the spec contains that information explicitly.

The best type is one you never have to write or generate from samples. But when you are consuming a third-party API with no spec, quicktype from JSON samples is the pragmatic choice.

Related Tools

Want API access + no ads? Pro coming soon.