Learn TypeScript

Creating some standard conditional utility types

Creating some standard conditional utility types

In this lesson, we will create a mapped type without certain keys from the type being mapped from. We will create two other utility types along the way.

Creating a type for removing values from a union type

We are going to create the utility types in the code editor below:

TypeScriptOpen exercise in CodeSandbox

The code contains a person object.

We are going to start by creating a type that removes values from a union type.

  • Let's start to create the type alias:
type RemoveFromUnion<T, K>

The type will take in a parameter for the union type, T, and the values to remove, K.

  • Add a condition for whether the values in K are in T:
type RemoveFromUnion<T, K> = T extends K
  • If the condition is true, then return never because we want to remove those values from the type. Otherwise, we can return T:
type RemoveFromUnion<T, K> = T extends K ? never : T;
  • Let's try this out:
type ContactKeys = RemoveFromUnion<keyof typeof person, "age">;
🤔

What is the type of ContactKeys?.

Nice!

This type is the same as a standard utility type called Exclude.

Creating a type that creates an object with certain keys from another type

We are going to create another utility type that creates an object type with specific keys from the type passed into it.

  • Let's start to create the type alias:
type ObjectWithKeys<T, K extends keyof T>

The type will take in a parameter for the object type, T, and the keys to include, K. The keys to include must be keys within T.

  • Complete the type as follows:
type ObjectWithKeys<T, K extends keyof T> = {
[P in K]: T[P];
};

The keys in K are mapped over, and the type for each key is looked up.

  • Let's try this out:
type Contact = ObjectWithKeys<typeof person, "name" | "email">;
🤔

What is the type of Contact?.

Nice!

This is the same type as a standard utility type called Pick.

Creating a type that creates an object without certain keys from another type

The final utility type we are going to create will leverage the other two types we have created. The type will create an object type without specific keys from the type passed into it.

  • Let's start to create the type alias:
type ObjectWithoutKeys<T, K extends keyof T>

The type will take in a parameter for the object type, T, and the keys to exclude, K. The keys to include must be keys within T.

  • Complete the type as follows by leveraging the other two utility types we have created:
type ObjectWithoutKeys<T, K extends keyof T> = ObjectWithKeys<
T,
RemoveFromUnion<keyof T, K>
>;
  • Let's try this out:
type Profile = ObjectWithoutKeys<typeof person, "name" | "email">;
🤔

What is the type of Profile?.

Nice!

This is the same type as a standard utility type called Omit.

Summary

The combination of generics, mapped types, and conditional types allow powerful utility types to be created. A wide range of standard utility types already exist - it's well worth looking through these to understand the functionality they offer and understand how they are implemented.

Next up, we will test our knowledge of conditional types with a quiz.

© 2023 Carl Rippon
Privacy Policy
This site uses cookies. Click here to find out more