Typescript utility types that you must know
Tags: typescript, webdev, beginners, tutorial
Published: 2023-04-02 14:05:22

Hello everyone, Today, In this article, we will go through some beneficial and essential utility types in Typescript that can make your life easier.

Utility types in Typescript are some predefined generic types that can be used to manipulate or create other new types. These types are available globally in all Typescript projects, so you don't need to add any dependencies to get these going.

## Table of contents

- [Partial](#partial)
- [Required](#required)
- [Omit](#omit)
- [Pick](#pick)
- [Multiple utility types together](#multiple-utility-types-together)
- [Readonly](#readonly)
- [Mutable](#mutable)
- [Exclude](#exclude)
- [Extract](#extract)
- [ReturnType](#returntype)
- [Parameters](#parameters)
- [NonNullable](#nonnullable)
- [Awaited](#awaited)
- [Awaited and ReturnType combined](#awaited-and-returntype-combined)
- [Conclusion](#conclusion)

### Partial
The first utility type we will look at is `Partial,` which, as It sounds, makes everything optional or partial.

Here is an example of **Partial** utility type:

```ts
interface Person {
  name: string;
  age: number;
  email: string;
}

// Define a new type called 'PartialPerson' that is a partial version of 'Person'
type PartialPerson = Partial<Person>;

// Same as:
// interface Person {
//   name?: string | undefined;
//   age?: number | undefined;
//   email?: string | undefined;
// }
```

### Required
The opposite to `Partial` is `Required` utility type, which makes everything required.

```ts
interface Person {
 name?: string | undefined;
 age?: number | undefined;
 email?: string | undefined;
}

// Define a new type called 'RequiredPerson' that is a required version of 'Person'
type RequiredPerson = Required<Person>;

// Same as:
// interface Person {
//   name: string;
//   age: number;
//   email: string;
// }
```

### Omit
You can use the `Omit` utility type to create a new type from an existing type, however, with some properties removed.

```ts
interface User {
  id: number;
  name: string;
  email: string;
  age: number;
}

type UserWithoutEmail = Omit<User, 'email'>;

// same as: 
// interface User {
//   id: string;
//   name: string;
//   age: number;
// }
```

We can also remove multiple properties by passing an `union`

```ts
interface User {
  id: number;
  name: string;
  email: string;
  age: number;
}

type UserWithoutEmailAndName = Omit<User, 'email' | 'name'>;

// same as: 
// interface User {
//   id: string;
//   age: number;
// }
```

### Pick
The opposite of `Omit` is the `Pick` utility type that allows you to create a new type that contains only a subset of properties from an existing type.

```ts
interface User {
  id: number;
  name: string;
  email: string;
  age: number;
}

type UserWithEmailAndName = Pick<User, 'email' | 'name'>;

// same as: 
// interface User {
//   name: string;
//   email: string;
// }
```

### Multiple utility types together
We can even use multiple utility types together. For example:

```ts
interface User {
  id: number;
  name: string;
  email: string;
  age: number;
}

type PartialPick = Partial<Pick<User, 'email' | 'name'>>;

// same as: 
// interface User {
//   name?: string | undefined;
//   email?: string | undefined;
// }
```

Another exmaple:
```ts
interface User {
  id: number;
  name: string;
  email: string;
  age: number;
}

type OmitPartialPick = Omit<Partial<Pick<User, 'email' | 'name'>>, 'email'>;

// same as: 
// interface User {
//   name?: string | undefined;
// }
```

### Readonly
`Readonly` utility types allow you to create a new type from an existing type set as `readonly,` which means we cannot modify any property after the initialization.

```ts
interface Person {
  id: number;
  name: string;
  age: number;
}

type ReadonlyPerson = Readonly<Person>;

// same as:
// interface Person {
//   readonly id: number;
//   readonly name: string;
//   readonly age: number;
// }

const person: ReadonlyPerson = {
  id: 1,
  name: 'John',
  age: 25
};

person.name = 'Mike'; // Error: Cannot assign to 'name' because it is a read-only property.

```

### Mutable
You can also create a `Mutable` type helper that allows you to convert all readonly types to mutable type.

```ts
interface Person {
  readonly id: number;
  readonly name: string;
  readonly age: number;
}

// The syntax for Mutable is as follows:
type Mutable<T> = {
  -readonly [P in keyof T]: T[P];
};

type MutablePerson = Mutable<Person>;

// same as:
// interface Person {
//   id: number;
//   name: string;
//   age: number;
// }

const person: MutablePerson = {
  id: 1,
  name: 'John',
  age: 25
};

person.name = 'Mike'; // Okay
person.id = 2; // Okay
```

### Exclude
`Exclude` utility type allows you to create a new type by removing members of an `union`

```ts
type NumberOrString = number | string;
type OnlyNumber = Exclude<NumberOrString, string>;

// same as:
// type OnlyNumber = number;

const num: OnlyNumber = 5;
const str: OnlyNumber = 'hello'; // Error: Type '"hello"' is not assignable to type 'number'.
```
You can even `exlude` mulitple members of an union:
```ts
type NumberStringOrBoolean = number | string | boolean;
type OnlyBoolean = Exclude<NumberStringOrBoolean, string | number>;

// same as:
// type OnlyBoolean = boolean;
```

### Extract
The opposite to `Exclude` is `Extract` utitlity type that allows you to pick **a** or **multiple** members from an union:

```ts
type NumberOrString = number | string | boolean;
type OnlyNumber = Extract<NumberOrString, number>;

// same as:
// type OnlyNumber = number;
```

### ReturnType
`ReturnType` utility type lets you to extract the return type of a function type. It takes a function type as an argument and returns the value type that the function returns.

```ts
function add(a: number, b: number): number {
  return a + b;
}

type AddReturnType = ReturnType<typeof add>;
// type AddReturnType = number;

// ---

function addStr(a: string, b: string): string{
  return a + b;
}

type AddReturnType2 = ReturnType<typeof addStr>;
// type AddReturnType2 = string;
```

### Parameters
The `Parameters` utility type lets you extract the type of parameters from a function.

```ts
function add(a: number, b: string, c:boolean): string {
  return a + b;
}

type AddReturnType = Parameters<typeof add>;
// type AddReturnType = [a: number, b: string, c:boolean];
```

### NonNullable
`NonNullable` utility type lets you to create a new type by excluding `null` and `undefined` from a given type.

```ts
type NullableString = string | null | undefined;

type NonNullableString = NonNullable<NullableString>;
// type NonNullableString = string;

const str1: NullableString = null;
const str2: NonNullableString = 'hello';
const str3: NonNullableString = null; // Error: Type 'null' is not assignable to type 'string'.
```

### Awaited
`Awaited` utility type allows you to extract the resolved type of a `promise` or other type that uses `await`.

```ts
type promiseNumber = Promise<number>

type justNumber = Awaited<Promise<number>>
// type justNumber = number
```

### Awaited and ReturnType combined
Here's an example of using `ReturnType` and `Awaited` together:

```ts
async function fetchData(): Promise<string> {
  // fetch data from API and return a string
}

type ResolvedResult = Awaited<ReturnType<typeof fetchData>>;
// type ResolvedResult = string
```
In this example, we define an async function that returns a `Promise` of a string `(Promise<string>).` We then use `ReturnType` to extract the return type of fetchData and pass it as an argument to `Awaited` to unwrap the promised's resolved type.

---

### Conclusion
These are some of the most used typescript utility types that are heavily used by other developers worldwide. It cleans your code and can be used to work with types more expressively and concisely. I hope you will find this article helpful, and if you think I missed any essential utility types, please let me know in the comments. Thanks for reading the article. See you all in my next article🐼.

**Visit:**
👨‍💻[My Portfolio](https://portfolio-khaki-iota-89.vercel.app/)
🏞️[My Fiverr](https://www.fiverr.com/sunnyislam990)
🌉[My Github](https://github.com/arafat4693)