0

I'm trying to convert a union type to an intersection type:

type UnionToIntersection<U> = // unknown code

type test = UnionToIntersection<{a: 1} | { b: 2}>
// typeof test should be {a: 1} & { b: 2}, an impossible type

This is just one step in a larger type function which will then merge the properties of {a:1} and {b:2} to make {a:1, b:2}. But that's a later step.

First step is I need to convert my union to an intersection. How can I do that?


For those wondering, it will then go into this:

export type SubpropertyMerge<T> = (
  T extends (...args: infer A) => infer R ? (
    (...args: A) =>  R
  ): (
    T extends object ? (
      T extends string | number | ((...args: any) => any) | symbol | boolean ? T
      : { [K in keyof T]: SubpropertyMerge<T[K]> }
    ) : T
  )
);

// SubpropertyMerge<{a: 1} & { b: 2}> === {a:1, b:2}
Seph Reed
  • 8,797
  • 11
  • 60
  • 125
  • I'm inclined to close this as a duplicate of [this question](https://stackoverflow.com/questions/50374908/transform-union-type-to-intersection-type) unless you can articulate a difference. Side note: `{a: 1} & {b: 2}` is not an impossible type, and it is equivalent to `{a:1, b: 2}`... maybe [you have this confusion](https://stackoverflow.com/questions/59722333/union-and-intersection-of-types)? – jcalz Jun 19 '21 at 00:50
  • I over simplified my situation. The "impossible" type is `{ foo: {a :1}} & { foo: {b: 2}}`, because foo will become never... or something of that nature. I haven't figured out the exact point at which intersections stop being... unintuitive to me specifically. – Seph Reed Jun 21 '21 at 16:48
  • [That's not impossible either](https://tsplay.dev/wOaZEm). Impossible types equivalent to `never` do exist, but I haven't seen any here yet. – jcalz Jun 21 '21 at 20:19
  • Last try: `{ a:1 } & { a:2 }`. – Seph Reed Jun 21 '21 at 22:46

1 Answers1

1

You can use this UnionToIntersection type:

export type UnionToIntersection<U> = (
  U extends any ? (k: U) => void : never
) extends (k: infer I) => void
  ? I
  : never
phry
  • 35,762
  • 5
  • 67
  • 81
  • This worked for a case where the type for U was specified. Unfortunately, my type for U is some other generic which extends a known type and that was just enough to break some things involving inference from it. – Seph Reed Jun 21 '21 at 19:48