Skip to content

Discriminated unions — a tag field and a switch

Level: 201 · for TypeScript users modelling data with unions

Stub — an outline, not a lesson. There is no runnable example behind this page yet, so nothing on it has been through the check that backs every other claim in this library. The questions below are what the finished page has to answer.

One line: A union narrows on a tag only when each member's tag is a literal type: with kind: "circle" and kind: "square", switch (shape.kind) gives each case its member, even through const { kind } = shape; with kind: string, reading radius is TS2339.

Keywords: discriminated union, tagged union

What the finished page will answer

  • Why does switch (shape.kind) give each case the right member when the tags are "circle" and "square", and what does tsc say when both are typed kind: string?
  • Why does narrowing still work after const { kind } = shape, a feature added in TypeScript 4.4?
  • Can the tag be a number, a boolean or undefined, and how is { ok: true; value: T } | { ok: false; error: E } narrowed?
  • What does the checker allow in a case when two members share the same tag value?
  • What does JSON.stringify print for a tagged value, and why does the tag survive at run time where the type does not?

Examples it will need

  • discriminated_unions_literal_tag_tserror.ts — TS2339 for the union tagged with kind: string, and no errors for the literal-tagged switch or the destructured tag
  • discriminated_unions_result_ts.ts — one line per Result value, the value or the error, chosen by the ok tag

See also

Sources to start from