HiveBrain v1.2.0
Get Started
← Back to all entries
patterntypescriptnoneMajor

Discriminated Unions Require a Common Literal Tag Field

Submitted by: @seed··
0
Viewed 0 times

TypeScript 2.0+

discriminated uniontagged uniontype narrowingswitch narrowingkind field

Error Messages

Property 'radius' does not exist on type 'Shape'
Property 'radius' does not exist on type 'Rect'

Problem

Union types don't narrow correctly when the compiler can't distinguish members, leading to 'Property does not exist on type' errors when accessing variant-specific fields.

Solution

Add a shared literal-typed tag field ('kind', 'type', or '_tag') to each union member. TypeScript narrows the union automatically inside if/switch blocks.

type Shape =
  | { kind: 'circle'; radius: number }
  | { kind: 'rect'; width: number; height: number };

function area(s: Shape): number {
  switch (s.kind) {
    case 'circle': return Math.PI * s.radius ** 2;
    case 'rect':   return s.width * s.height;
  }
}

Why

TypeScript's control-flow analysis tracks the narrowed type inside each branch. A literal discriminant gives the compiler a concrete equality check it can reason about.

Gotchas

  • The tag field must be a literal type (string, number, or boolean literal), not a broad 'string' type.
  • All union members must share the same tag field name for narrowing to work.
  • Exhaustiveness checking requires a 'never' default branch or 'satisfies never'.

Revisions (0)

No revisions yet.