Search code examples
javascripttypescriptunion-types

Why does typescript give a type error on type unions?


Whenever I have to work with objects that have a combined union type, typescript complains about the properties that I try to access and I don't get autocompletion either. For example this:

interface A {
  id: string;
  value: number;
}

interface B {
  result: string;
}

export type Types = A | B;

function test(obj: Types) {
  obj.result;  // want to work with obj as though it implements interface B
}

I get errors when I access result, id, and value from typescript:

Property 'result' does not exist on type 'Types'.
  Property 'result' does not exist on type 'A'

Is there any way that I can narrow down the interface type so that I would get a better IDE experience?


Solution

  • interface A {
      type:'A';
      id: string;
      value: number;
    }
    
    interface B {
      type:'B';
      result: string;
    }
    
    export type Types = A | B;
    
    function test(obj: Types) {
      if(obj.type==='B'){
        obj.result;
      }
    }
    

    You need a common field to teach TS how to recognize type A or B.

    https://www.typescriptlang.org/docs/handbook/advanced-types.html#discriminated-unions