Mastering TypeScript Types with Pick, Exclude, and Omit

Table of contents

No heading

No headings in the article.

TypeScript provides several utility types, such as Pick, Exclude, and Omit, which can be confusing to use at times. In this post, we will discuss each of these utility types in detail, so you can use them effectively.

The Pick utility type is the easiest to use among the three. It is defined as follows:

type Pick<T, K extends keyof T> = {
  [P in K]: T[P];
};

The Pick type has two generic parameters: T represents the type from which we want to pick properties, and K is a union of keys of T that we want to pick. Here is an example of how to use the Pick type:

type Person = {
  firstName: string;
  lastName: string;
  age: number;
  address: string;
};

type PersonInfo = Pick<Person, 'firstName' | 'age'>;

const person: Person = {
  firstName: 'John',
  lastName: 'Doe',
  age: 30,
  address: '123 Main St',
};

const personInfo: PersonInfo = {
  firstName: person.firstName,
  age: person.age,
};

console.log(personInfo); // { firstName: 'John', age: 30 }

Note that the second argument to Pick is a union of keys present in the type of the first argument.

Now let's talk about the Exclude type. It is used to exclude one or more types from a union type. It is defined as follows:

typescriptCopy codetype Exclude<T, U> = T extends U ? never : T;

The Exclude type has two generic parameters, T and U. It checks if T is assignable to U. If it is, then it will return never, which means that T is excluded from the type. Otherwise, it returns T. Here is an example of how to use Exclude:

typescriptCopy codetype A = string | number | boolean;

type B = Exclude<A, number>; // Output: B is of type string | boolean
type C = Exclude<A, string | number>; // Output: C is of type boolean

Note that Exclude only works with union types, not interfaces.

If your use case is to remove a certain property from an object type, then Omit is the way to go. The Omit type is defined using the Pick and Exclude types, as follows:

type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;

The Omit type takes two type arguments: the first argument is the original type from which properties will be omitted, and the second argument is a union of string literal types representing the names of the properties to be omitted. Here is an example of how to use Omit:

interface Product {
  id: number;
  name: string;
  price: number;
  category: string;
}

type ProductInfo = Omit<Product, 'id' | 'category'>;

const a: ProductInfo = {
  name: "xyz",
  price: 123,
}

I hope this post helps you to better understand these three different utility types. If you have any feedback or questions, please leave them in the comments below.