marcus-linmarkson
marcus-linmarkson

Reputation: 363

Typescript - conditional property base on another property with Union type gives an error

I prepared an union type like below:

export type UnionType =
  | {
      id: 1;
      obj: {
        a: string;
        b: string;
      };
    }
  | {
      id: 2;
      obj: {
        a: string;
      };
    };

Unfortunately it breaks within my selector, when I want to access b property like: xxx.b.

export const selectB = createSelector(
  [selectObj],
  (someArr: UnionType[]) =>
    (someArr.find(ob => ob.id === 1)
      ?.obj?.b) || '',
);

The error is:

Property 'b' does not exist on type '{ a: string; }'.

Can we somehow work around it?

Upvotes: 0

Views: 67

Answers (2)

marcus-linmarkson
marcus-linmarkson

Reputation: 363

I ended up doing this:

obj["b"] 

Upvotes: 0

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 249486

The problem (at least based on the error) is that if you have a discriminated union, you must perform checks to see in which of the cases you are. You can do this either using a series of if statements, or a switch on the discriminant field:


declare let o: UnionType;

o.obj.b // error
switch(o.id) {
  case 1: o.obj.b; break // ok here
  case 2: o.obj.b; break // not ok on this branch
  default: assertNever(o); // Optional, ensure no casses are missed, o shoudl be never
}

function assertNever(o: never) {
  throw new Error("Not supported")
}

Playground Link

Upvotes: 2

Related Questions