简体   繁体   中英

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?

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

我最终这样做了:

obj["b"] 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM