Object utility types

This is series of illustrative exercises on composing utility types into much more sophisticated utility types for working with objects.

Filtering an interface by value

When filtering an interface, you will often find yourself using the Pick utility type, which filters an object type by keys.

Suppose we wanted a ValuePick utility which picks based on the value type. Let's start by setting up an mapped type that effectively constructs an identical type to the one we pass in as T.

Even though this didn't really accomplish anything, it helps establish a starting point that we can expand on to construct the type. The next step is to examine T[Key] with extends, to see if it is fully-enclosed by the value type V.

The issue here is that the resulting type still has all the original object's keys, with values that don't match type V rewritten as never. This creates a compilation error, even though there is no possible value that can be assigned to the key.

Rather than retrieve T[Key] (the value type), let's retrieve Key (the key from our object T).

We can now perform type flattening to retrieve the union of all value types for the resulting object, which will automatically filter out never.

Now that we can construct a union of keys that we are interested in, we can pass them as the second type parameter of Pick (the first parameter being our object type T).

We can optionally combine these two types into a single ValuePick type.

Now that you have seen how to construct a complex type, see if you can read the type below and comprehend how it works.

This utility type uses a technique for checking strict equality of two types.

strict type equality
[A] extends [B] ? [B] extends [A] ? equal : never : never

Was this page helpful?