consolelog.tools

Discriminated Union Generator

Compose a tagged union from a model — a discriminant key plus a list of variants, each with its own typed fields — and get a complete, type-safe bundle: the union type, a type guard per variant, an exhaustive switch with a never default for compile-time exhaustiveness, factory constructors, and a match() pattern-matcher. The preview updates live as you edit and the whole model is captured in a shareable URL.

About this ToolHow it works, benefits & use cases

A discriminated (tagged) union is the TypeScript pattern that makes state machines, reducer actions and tagged results fully type-safe: every variant shares one literal property — the discriminant, like type, kind or status — and the compiler uses that tag to narrow the type inside a switch or if. This generator is a model-driven builder, not a parser: you declare a discriminant key and a list of variants, give each variant its own typed fields (with optional flags), and it assembles a complete bundle you can switch between. That bundle includes the union type itself (optionally as named interfaces such as Circle), a type guard per variant (isCircle(s): s is Circle), an exhaustive switch handler whose never default fails the build if you ever add a variant and forget to handle it, factory constructor functions per variant, and a match() helper that pattern-matches on the tag with a strongly typed handler map. Presets cover the common shapes — geometric shapes, async state, Redux-style actions, an API result and a form-field union — and the live preview re-renders instantly as you edit. The whole model is captured in a shareable URL and everything is generated in your browser.

How to Use

  1. 1Set a Union name (e.g. Shape) and a Discriminant key (e.g. kind, type, or status).
  2. 2Add variants with the Add variant button; give each a tag literal such as circle or LOADING.
  3. 3On each variant, add field rows — a property name plus its TypeScript type — and tick "opt" for optional fields.
  4. 4Toggle options: export declarations, named variant interfaces, and a readonly discriminant tag.
  5. 5Use the output selector to switch the live preview between Union, Guards, Switch, Factories, match() or All.
  6. 6Or start from a preset (Shapes, Async state, Redux action, API result, Form field), then copy, download, or share.

Key Benefits

  • Model-driven builder: compose variants and fields visually instead of hand-typing every branch
  • Emits a full bundle — union, per-variant type guards, exhaustive switch, factories and a match() helper
  • The generated switch uses a never default for compile-time exhaustiveness checking
  • Optional named variant interfaces (e.g. Circle) or anonymous inline object members
  • Strongly typed match() handler map so each branch receives the narrowed variant type
  • Five presets covering shapes, async state, Redux actions, API results and form fields
  • Live preview, shareable URL, and fully in-browser generation with no upload

Common Use Cases

  • Modeling async data as idle / loading / success / error with type-safe payloads
  • Defining Redux or reducer action types that share a type discriminant
  • Typing API results with ok and err branches that carry different fields
  • Building shape or geometry unions where each kind has its own dimensions
  • Generating guards and an exhaustive switch so a forgotten case becomes a compile error
  • Producing factory constructors and a match() helper alongside the type in one paste

The tagged union type (+ named variant interfaces)

export interface Circle {
  kind: 'circle';
  radius: number;
}

export interface Square {
  kind: 'square';
  size: number;
}

export interface Triangle {
  kind: 'triangle';
  base: number;
  height: number;
}

export type Shape =
  | Circle
  | Square
  | Triangle;
Compile-time exhaustiveness guaranteed

The generated switch assigns the value to a never in its default case. Add a variant later and forget to handle it, and TypeScript fails the build.

3variants4fields0optional

Presets

Union shape

e.g. interface Circle

freeze the discriminant

Variants

What a discriminated union buys you

A discriminated (tagged) union shares one literal property — the discriminant — across every variant. TypeScript uses that tag to narrow the type inside a switch or if, so each branch only sees the fields that branch actually has.

A complete bundle, not just a type

Beyond the union itself, the generator emits a type guard per variant, an exhaustive switch whose never default catches unhandled cases at compile time, factory constructors, and a match() helper that pattern-matches on the tag with a handler map.

Was this tool helpful?

Share Your Experience

Help others discover this tool!

Related tools