Essential TypeScript Utility Types
Published: 2023-05-28 08:09:40

If you have used typescript in your project then there is a fair chance that you have come across a situation where you have to write 100s of types and it leads you to the thought can I reuse the types that I have already defined? At least I have once thought this until I have not heard about utility types in typescript. One of the excellent features of typescript that is basically there to solve this problem.

In this, we will discuss some essential and valuable utility types that you must know before jumping into the world of typescript.

1. <a rel="noopener" target="_blank" href="#partial">Partial</a>
2. <a rel="noopener" target="_blank" href="#required">Required</a>
3. <a rel="noopener" target="_blank" href="#omit">Omit</a>
4. <a rel="noopener" target="_blank" href="#pick">Pick</a>
5. <a rel="noopener" target="_blank" href="#readonly">Readonly</a>
6. <a rel="noopener" target="_blank" href="#mutable">Mutable</a> 
7. <a rel="noopener" target="_blank" href="#return-type">ReturnType</a>
8. <a rel="noopener" target="_blank" href="#parameter">Parameter</a>
9. <a rel="noopener" target="_blank" href="#awaited">Awaited</a>
10. <a rel="noopener" target="_blank" href="#non-nullable">Non Nullable</a>
11. <a rel="noopener" target="_blank" href="#exclude">Exclude</a>
12. <a rel="noopener" target="_blank" href="#extract">Extract</a>

---

<div>
<a id="partial"></a>
## Partial
The **`Partial<Type>`** utility type in TypeScript allows you to create a new type that has all properties of the original **`Type`**, but with each property marked as optional. This means you can assign undefined or a value of the property's type to these optional properties. The **`Partial<Type>`** type is particularly useful when you want to define or manipulate objects where not all properties are required.

Here's an example that demonstrates the usage of **`Partial<Type>`**:</div>

```typescript

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

/**
* here we have to provide all properties, otherwise typescript will through on type checking as all attributes are mandatory
*/
const existingUser: User = {
  id: 1,
  name: "John Doe",
  email: "john@example.com",
  age: 30,
};

/**
* here we can skip any attribute because using the Partial utility, we inform typescript that all its attributes are optional
*/

const newUser: Partial<User> = {
  name: "Jane Smith",
  email: "jane@example.com",
};

/**
 * Partial<User>
 * {
 * id?: number | undefined;
 * name?: string | undefined;
 * email?: string | undefined;
 * age?: number | undefined;
 * }
 */
```

---
<div>
<a id="required"></a>
## Required

The **`Partial<Type>`** utility type in TypeScript allows you to create a new type that has all properties of the original **`Type`**, but with each property marked as optional. This means you can assign undefined or a value of the property's type to these optional properties. The **`Partial<Type>`** type is particularly useful when you want to define or manipulate objects where not all properties are required.

Here's an example that demonstrates the usage of **`Partial<Type>`**:</div>

```typescript

interface User {
  id?: number | undefined;
  name?: string | undefined;
  email?: string | undefined;
  age?: number | undefined;
}

/**
 * Here you have to provide all attributes b/c by using Require utility we have made all attributes of User interface compulsory
 */
const newUser: Required<User> = {
  id: 1,
  name: 'John Doe',
  email: 'john@example.com',
  age: 30,
};

/**
 * Required<User>
 * {
 * id number;
 * name string;
 * email string;
 * age number;
 * }
 */

```

---
<div>
<a id="omit"></a>
## Omit
The **`Omit<Type, Keys>`** utility type in TypeScript allows you to create a new type that excludes specified properties from the original **`Type`**. This means you can create a new type that includes all properties of the original type except for the specified keys.

Here's an example that demonstrates the usage of **`Omit<Type, Keys>`**:</div>

```typescript

interface Book {
  id: number;
  author: string;
  title: string;
  category: string;
  description: string;
}

type BookPreview = Omit<Book, 'description' | 'category'>;

/**
 * type BookPreview = {
 *   id: number;
 *   author: string;
 *   title: string;
 * }
 */

```

---

<div>
<a id="pick"></a>
## Pick

The **Pick** utility is exactly the opposite of **Omit** utility.The **`Pick<Type, Keys>`** utility type in TypeScript allows you to create a new type by selecting specific properties from an existing type. It helps you extract a subset of properties and create a new type with only those selected properties.

Here's an example that demonstrates the usage of **`Pick`**:</div>

```typescript
interface Book {
  id: number;
  author: string;
  title: string;
  category: string;
  description: string;
}

type BookPreview = Pick<Book, 'id' | 'author' | 'title'>;

/**
 * type BookPreview = {
 *   id: number;
 *   author: string;
 *   title: string;
 * }
 */

```

---
<div>
<a id="read-only"></a>
## Readonly

The **`Readonly<Type>`** utility type in TypeScript is used to create a new type where all properties of the original type are read-only. It makes every property in the type immutable, meaning they cannot be modified once assigned a value.

Here's an example that demonstrates the usage of **`Readonly`**:</div>

```typescript
interface Book {
  id: number;
  author: string;
  title: string;
  category: string;
  description: string;
}

type ReadOnlyBook = Readonly<Book>;

/**
 * type BookPreview = {
 *  readonly id: number;
 *  readonly author: string;
 *  readonly title: string;
 *  readonly category: string;
 *  readonly description: string;
 * }
 */

//if you don't provide all type then typescript will give error on type checking
const odacy: ReadOnlyBook = {
  id: 1,
  author: 'Ben',
  title: 'Odacy',
  category: '',
  description: '',
};

```

---
<div>
<a id="mutable"></a>
## Mutable

Now since we talk about readonly utility. There is also very useful helper function that use in typescript code base and that is **`Mutable<Type>`.**The **`Mutable<Type>`** utility type is not a built-in TypeScript utility type. However, you can create your own **`Mutable`** utility type to reverse the immutability of a type. It allows you to make the properties of a type mutable again, even if they were originally defined as read-only.

Here's an example of how you can create the **`Mutable`** utility type and use it:</div>

```typescript
interface ReadOnlyBook {
  readonly id: number;
  readonly author: string;
  readonly title: string;
  readonly category: string;
  readonly description: string;
}

type Mutable<T> = {
  -readonly [P in keyof T]: T[P];
};

const mutableBook: Mutable<ReadOnlyBook> = {
  id: 30,
  author: 'John Doe',
  title: 'odacy',
  category: 'novel',
  description: '....',
};

mutableBook.title = 'Jane Smith'; // Valid: 'name' is mutable
mutableBook.id = 40; // Valid: 'age' is mutable
```

---
<div>
<a id="return-type"></a>
## ReturnType

The **`ReturnType<Type>`** utility type is a built-in TypeScript utility type that extracts the return type of a function or constructor type.

Here's an example that demonstrates the usage of **`ReturnType`**:</div>

```typescript
interface Book {
  id: number;
  author: string;
  title: string;
  category: string;
  description: string;
}

const getAuthorName = (book: Book): string => {
  return book.author;
};

type author = ReturnType<typeof getAuthorName>;
/**
 * type author = string
 */

```

---
<div>
<a id="parameter"></a>
## Parameter

The **`Parameters<Type>`** utility type is a built-in TypeScript utility type that extracts the parameter types of a function type or constructor type as a tuple.

Here's an example that demonstrates the usage of **`Parameters`**:</div>

```typescript
interface Book {
  id: number;
  author: string;
  title: string;
  category: string;
  description: string;
}

const setAuthorName = (book: Book, authorName: string): Book => {
  book.author = authorName;
  return book;
};

type author = Parameters<typeof setAuthorName>;
// /**
//  * type author = [book: Book, authorName: string]
//  */
```

---
<div>
<a id="awaited"></a>
## Awaited

The **`Awaited<Type>`** utility type is a built-in TypeScript utility type that extracts the resolved type of a promise. It unwraps the generic type parameter of a **`Promise<T>`** and gives us the actual type **`T`**.

Here's an example that demonstrates the usage of **`Awaited`**:</div>

```typescript
async function fetchData(): Promise<string> {
  return "Data fetched";
}

type FetchedData = Awaited<ReturnType<typeof fetchData>>;

async function printData(): Promise<void> {
  const data: FetchedData = await fetchData();
  console.log(data); // Output: Data fetched
}

printData();
```

---
<div>
<a id="non-nullable"></a>
## Non Nullable 

NonNullabe utility type allow you to create new type from the existing one excluding the undefined and null from the existing one

Here’s an example that demonstrates the usage of NonNullable:</div>

```typescript
type Author = string | undefined | null;
type NonNullableAuthor = NonNullable<Author>;
```

---
<div>
<a id="exclude"></a>
## Exclude

The **`Exclude<T, U>`** utility type in TypeScript creates a new type that excludes the types present in the union **`U`** from the union **`T`**. It essentially removes the common types between **`T`** and **`U`**.

Here's an example to illustrate the usage of **`Exclude`**:</div>

```typescript
type BookCategory =
  | 'fiction'
  | 'documentary'
  | 'mystery'
  | 'thriller'
  | 'comedy';
type SuspenseCategory = 'thriller' | 'mystery';

type NonSuspenseCategory = Exclude<BookCategory, SuspenseCategory>;

/**
 * type NonSuspenseCategory = "fiction" | "documentary" | "comedy"
 */

```

---
<div>
<a id="extract"></a>
## Extract

The **`Extract`** utility is exactly the opposite of **`Exclude`** utility. The **`Extract`** utility type in TypeScript allows you to create a new type by extracting specific members from a union type.

Here's an example to illustrate the usage of **`Extract`**</div>

```typescript
type BookCategory =
  | 'fiction'
  | 'documentary'
  | 'mystery'
  | 'thriller'
  | 'comedy';
type SuspenseCategory = Extract<BookCategory, 'thriller' | 'mystery'>;

/**
 * type SuspenseCategory = "mystery" | "thriller"
 */

```
---