Convert JSON to TypeScript Discriminated Union Types

Learn how to create TypeScript discriminated unions from JSON objects that share a common tag field. Enable exhaustive pattern matching.

Complex Types

Detailed Explanation

Discriminated Unions from JSON

A discriminated union (also called a tagged union) is a pattern where multiple interfaces share a common literal-type property that TypeScript uses to narrow the type in conditional branches.

Example JSON

[
  { "type": "text", "content": "Hello world" },
  { "type": "image", "url": "https://cdn.example.com/photo.jpg", "alt": "A photo" },
  { "type": "video", "url": "https://cdn.example.com/clip.mp4", "duration": 120 }
]

Generated TypeScript

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

interface ImageBlock {
  type: "image";
  url: string;
  alt: string;
}

interface VideoBlock {
  type: "video";
  url: string;
  duration: number;
}

type Block = TextBlock | ImageBlock | VideoBlock;

How the Converter Detects the Discriminant

The tool looks for a string property that:

  1. Exists in every array element.
  2. Has a small set of unique literal values.
  3. Correlates with different shapes — elements with "type": "text" have different keys than those with "type": "image".

When these conditions are met, the converter generates separate interfaces and a union type.

Pattern Matching

function renderBlock(block: Block) {
  switch (block.type) {
    case "text":
      return block.content; // TS knows block is TextBlock
    case "image":
      return block.url;     // TS knows block is ImageBlock
    case "video":
      return block.duration; // TS knows block is VideoBlock
  }
}

TypeScript narrows the type inside each case branch, giving you access to the specific properties without type assertions.

Exhaustiveness Checking

Add a default branch with never to catch missing cases:

default:
  const _exhaustive: never = block;
  throw new Error(`Unhandled block type: ${(block as any).type}`);

If you later add a "code" block type and forget to handle it, TypeScript will report an error at compile time.

Use Case

You are building a rich content editor where the API returns an array of heterogeneous blocks (text, image, video, code) and you need type-safe rendering logic for each variant.

Try It — JSON to TypeScript

Open full tool