Furman
Furman

Reputation: 2395

TypeScript conditional Exclude type exclude from interface

According to documentation, I can use predefined Exclude type to exclude certain properties from certain type:

type Test = string | number | (() => void);

type T02 = Exclude<Test, Function>;

However if instead of Test type I'd have Test interface, it doesn't seems to work. How can I achieve similiar result in below case?

interface Test {
  a: string;
  b: number;
  c: () => void;
} 

// get somehow interface with excluded function properties??

Upvotes: 5

Views: 2781

Answers (1)

jcalz
jcalz

Reputation: 328473

To get this effect you need to figure out which properties match Function, and then selectively exclude them. Equivalently we find which properties do not match Function, and then selectively include them. This is more involved than just excluding some pieces of a union; it involves mapped types as well as conditional types.

One way to do this is as follows:

type ExcludeMatchingProperties<T, V> = Pick<
  T,
  { [K in keyof T]-?: T[K] extends V ? never : K }[keyof T]
>;

type T02 = ExcludeMatchingProperties<Test, Function>;
// type T02 = {
// a: string;
// b: number;
// }

Examining ExcludeMatchingProperties<T, V>, we can note that the type { [K in keyof T]-?: T[K] extends V ? never : K }[keyof T] will return the keys in T whose properties are not assignable to V.

If T is Test and V is Function, this becomes something like

{ 
  a: string extends Function ? never : "a"; 
  b: number extends Function ? never : "b"; 
  c: ()=>void extends Function ? never : "c" 
}["a"|"b"|"c"]

, which becomes

{ a: "a"; b: "b"; c: never }["a"|"b"|"c"]

, which becomes

{ a: "a"; b: "b"; c: never }["a"] | 
{ a: "a"; b: "b"; c: never }["b"] | 
{ a: "a"; b: "b"; c: never }["c"]

, or

"a" | "b" | never

, or

"a" | "b"

Once we have those keys, we Pick their properties them from T (using the Pick<T, K> utility type):

Pick<Test, "a" | "b">

which becomes the desired type

{
  a: string,
  b: number
}

Okay, hope that helps; good luck!

Link to code

Upvotes: 16

Related Questions