1

I have the following union type:

type Foo = 'ol' | 'ul';

and I somehow want to convert that to this using a generic (as Foo might change to include others)

type Bar = OtherType<'ol'> & OtherType<'ul'>;

I'm not quite sure where to start...

EDIT: a more concrete example with React is:

type Elements = 'ol' | 'ul';

// ... somehow transform to:

type Props = JSX.IntrinsicElements['ol'] & JSX.IntrinsicElements['ul']
leepowell
  • 3,838
  • 8
  • 27
  • 35

2 Answers2

0
import React from 'react'


// credits goes to https://stackoverflow.com/a/50375286
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
  k: infer I
) => void
  ? I
  : never;

type OtherType<T extends keyof JSX.IntrinsicElements> = UnionToIntersection<JSX.IntrinsicElements[T]>

type Result = OtherType<'ol' | 'ul'>;

declare var x: Result
declare var y: JSX.IntrinsicElements['ol'] & JSX.IntrinsicElements['ul']

x = y // ok

y = x // ok

Playground

Union distribution will do the work for you

0

Here's a solution which will work in general, when OtherType may not distribute over unions: it takes advantage of contravariance of function parameter types in order to convert a union to an intersection.

type MakeIntersection<T> = (T extends infer U ? (x: OtherType<U>) => void : never) extends (x: infer V) => void ? V : never

Playground Link

kaya3
  • 47,440
  • 4
  • 68
  • 97