Typescript: check if a type is a union

So it seems I’ve come up with an answer myself!

Here is the type (thanks Titian Cernicova-Dragomir for simplifying it!):

type IsUnion<T> = [T] extends [UnionToIntersection<T>] ? false : true

type Foo = IsUnion<'abc' | 'def'> // true
type Bar = IsUnion<'abc'> // false

And again UnionToIntersection of jcalz came in handy!

The principle is based on the fact that a union A | B does not extend an intersection A & B.

Playground

UPD. I was silly enough to not develop my type from the question into this one, which also works fine:

type IsUnion<T, U extends T = T> =
    (T extends any ?
    (U extends T ? false : true)
        : never) extends false ? false : true

It distributes union T to constituents, also T and then checks if U which is a union extends the constituent T. If yes, then it’s not a union (but I still don’t know why it doesn’t work without adding extends false ? false : true, i.e. why the preceding part returns boolean for unions).

Leave a Comment