简体   繁体   中英

How to go from a mapped type to a discriminated union

Apologises if this question has already been asked. I tried hard to find the solution but I'm probably not searching with the right terms.

My problem starts with this structure. This is a simple mapped type:

type Mapped = {
  square: {
    size: number;
  };
  rectangle: {
    width: number;
    height: number;
  };
};

I then have a type that it trying to create a union:

type Unionize<T> = {
  name: keyof T;
  data: T[keyof T];
};

type Out = Unionize<Mapped>;

It yields this type:

type Generated = {
  name: "square" | "rectangle";
  data: {
    size: number;
  } | {
    width: number;
    height: number;
  };
}

But really what I would like is this because I then would be able the leverage discriminated union to infer and check data properties.

type Wanted = {
  name: "square";
  data: {
    size: number;
  };
} | {
  name: "rectangle";
  data: {
    width: number;
    height: number;
  };
}

Instead of generating the name and data types independently using keyof T , first use a mapped type to put together the correct name and data for each key of T and then index that by keyof T to take the union.

type Unionize<T> = {
  [P in keyof T]: {
    name: P;
    data: T[P];
  }
}[keyof T];

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