Albert Gao
Albert Gao

Reputation: 3773

How to remove an blank interface type from an union in Typescript

type A = {}

 interface B {
  defaultText: string | null;
}

 interface C {
  json: any;
}

 interface D {
  rowsCollection: {item:string[]};
}

 type Union =
  | A
  | B
  | C
  | D;

The question here is how to remove the A from Union?

It is easy for removing the other type liketype UnionWithoutB = Exclude<Union, B>, the UnionWithoutB here will be A|C|D

but type UnionWithoutA = Exclude<Union, A> will give you never.

My question is: How to remove the blank interface type A here from the union type Union in Typescript?

These are types generated from GraphQL schema, and we do not have the control over them. Please solve without changing the current types but only adding new.

Upvotes: 1

Views: 306

Answers (1)

Ritik Mishra
Ritik Mishra

Reputation: 718

This should do the trick

type RemoveBlankInterfaceFromUnion<T> = 
  T extends infer U 
    ? {} extends U 
      ? never 
      : U
    : never
;

It works by using distributive conditional types to break up the union and omit anything that the type {} is assignable to.

Typescript playground


The reason that Exclude<Union, {}> gives never is because all object types in Typescript are assignable to {} for the same reason that { apple: number; banana: string } is assignable to { apple: number }.

Upvotes: 1

Related Questions