typescript type_narrowing_error ai_generated true

Property 'X' does not exist on type 'A | B'. Property 'X' does not exist on type 'B'.

ID: typescript/ts-discriminated-union-error

Also available as: JSON · Markdown
88%Fix Rate
90%Confidence
50Evidence
2023-01-01First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
5 active

Root Cause

TypeScript cannot narrow a union type because it lacks a discriminant property. Add a common literal type field.

generic

Workarounds

  1. 92% success Add a discriminant property with literal types to the union members
    interface Circle { kind: 'circle'; radius: number; }
    interface Square { kind: 'square'; side: number; }
    type Shape = Circle | Square;
    
    function area(s: Shape) {
      switch (s.kind) {
        case 'circle': return Math.PI * s.radius ** 2;
        case 'square': return s.side ** 2;
      }
    }

    Sources: https://www.typescriptlang.org/docs/handbook/2/narrowing.html#discriminated-unions

  2. 85% success Use 'in' operator for narrowing when no discriminant exists
    if ('radius' in shape) {
      // TypeScript knows this is Circle
      console.log(shape.radius);
    }

    Sources: https://www.typescriptlang.org/docs/handbook/2/narrowing.html#the-in-operator-narrowing

Dead Ends

Common approaches that don't work:

  1. Use type assertions (as TypeA) to access the property 70% fail

    If the runtime value is actually TypeB, accessing TypeA properties causes undefined behavior

Error Chain

Leads to:
Preceded by:
Frequently confused with: