Conditional types in TypeScript
In my previous article I gave you a short introduction to mapped types in TypesScript which are especially powerful feature when combined with conditional types.
The conditional types give you an opportunity to perform a non-uniform mapping. In addition, it’s possible to pick a certain subset of a string literals union, which can be used with the Pick generic type.
In this post I’ll familiarize you with the concept of the conditional types and provide several simple use cases.
Picking certain properties
Suppose you have an existing interface and you want to create a new type based on it. Obviously, you should you the Pick mapping type and provide a string literals union as the second type argument (the properties desired in the new type).
However, it’s a common scenario when you want to pick all the properties except for one (in general more properties should remain rather than be removed from a new type). Instead of typing a long list of properties, you can use a built-in conditional type, namely the Exclude:
Using the built-in tool is nice and easy, however it’s always a good idea to understand how things work under the hood so that you can accomplish a more challenging goal. Let’s take a look at implementation:
It simply means that given a string literals union (under T type variable) a check is performed if each string is assignable to a string literals union under the second type variables (U variable). If so, never is returned (a property is not present in a resulting union), otherwise a given string literal is added to the resulting union.
Null not allowed
TypeScript provides the built-in NonNullable conditional type which should be use in order to remove the null from a source union type.
However, you may want to be more strict about an existing interface and disable null assignment to each object property. It’s a moment when the knowledge of how conditional types work under the hood becomes precious.
The NonNullableObject is a generic type alias built with the aid of both mapped and conditional types.
However, you can do even better.