typescripttypescript3.0

Is it possible to Exclude an empty object from a union?


I have a union of two types, one of which is an empty obj.

type U = {} | { a: number } // | { b: string } | { c: boolean } ....

I would like to exclude the empty object from the union however Exclude is no help

type A = Exclude<U, {}>
// A = never

I tried using as const but it's the same result

const empty = {} as const
type Empty = typeof empty
type U = Empty | { a: number }
type A = Exclude<U, Empty>
//type A = never

The extra Irony is that excluding the other properties is straightforward

  type B = Exclude<U, { a: number }>
  // type B = {}

TS Playground

So is it possible to exclude an empty interface from other interfaces in a union?


Solution

  • Answering my own question..

    If you use AtLeastOne from @lukasgeiter answer here: Exclude empty object from Partial type

    you can do the following:

    type AtLeastOne<T, U = {[K in keyof T]: Pick<T, K> }> = Partial<T> & U[keyof U];
        
    type ExcludeEmpty<T> = T extends AtLeastOne<T> ? T : never; 
        
    type U = {} | { a: number } | { b: string }
        
    type Foo = ExcludeEmpty<U> // { a: number } | { b: string }
    

    TSplayground