Better Code Quality with TypeScript’s Utility Types: Pick, Partial, and Omit
Tags: typescript, coding, beginners, productivity
Published: 2023-08-14 16:28:12

#Introduction

I see a lot of projects that don't use TypeScript's type helpers like `Pick`, `Partial`, and `Omit`. These are very powerful tools that can create new interfaces, making your code cleaner and easier to reason about. In many cases, developers tend to avoid using these helpers due to unfamiliarity or the perceived complexity, but they can greatly enhance code quality.

#The Problem

Let's say we have a large User interface that's being used across the app in various functions. And because we use it in so many places, we have to make the properties optional to fit various use cases. This, however, leads to a lack of clarity about what is truly required in different contexts, making the code more prone to errors and harder to understand. For example:

```Typescript
interface User {
  id?: number
  name?: string
  email?: string
  password?:string
  phone?: string
}
```

And we have some functions that use the User interface like so:

```Typescript
function updateUser(user: User) {
  // ...
}

function sendEmailNotification(user: User) {
  // ...
}

function logUserDetails(user: User) {
  // ...
}
```

This approach may seem convenient, but it has some significant drawbacks:

- **Lack of Precision:** Using the entire User interface in each function means that all properties are considered optional, even when certain properties are required for a specific function. For instance, the `updateUser` function might need the `id`, but by marking it as optional, you risk runtime errors if it's not provided.

- **Poor Maintainability:** Any change to the User interface could inadvertently affect all functions, creating a fragile codebase. For example, if you add a property to the User interface, you'll need to ensure that it doesn't disrupt the existing functions, leading to increased complexity and a higher chance of mistakes.

- **No Flexibility: **The broad use of the User interface across functions prevents you from enforcing specific constraints where needed. For example, the `sendEmailNotification` function might only need the `name` and `email`, but the lack of constraints means that developers could accidentally pass in unnecessary or incorrect data, leading to bugs or security concerns.

- **Overhead and Confusion:** By using a general interface everywhere, it becomes harder for developers to understand what each function expects and returns. This not only slows down the development process but also makes code reviews and debugging more challenging, as the intended behavior is obscured.

By addressing these issues with more specific types like `Partial`, `Pick`, and `Omit`, you can create a codebase that is more robust, maintainable, and clear.

#Solutions

These three TypeScript helpers allow you to create more specific and efficient types based on existing ones.

##Partial

`Partial<Type>` makes all properties of `Type` optional. It's useful when you want to work with subsets of an object.

When updating a user, you might not need to provide all the fields. Here's how Partial can be used:

```Typescript
function updateUser(user: Partial<User>) {
  // Update only the provided fields of the user
  // ...
}
```

Here we can pass the properties we want to update, and we don't need to update the whole user.

##Pick

`Pick<Type, Keys>` creates a new type by picking a set of properties `Keys` from `Type`.

When notifying a user via email, you might only need the name and email fields. Here's how `Pick` can help:

```Typescript
function sendEmailNotification(user: Pick<User, 'name' | 'email'>) {
  // Send an email to the user using the name and email
  // ...
}
```

##Omit

`Omit<Type, Keys>` creates a new type by omitting a set of properties `Keys` from `Type`.

For logging user details without sensitive information like email and password, you can use `Omit`:

```Typescript
function logUserDetails(user: Omit<User, 'email' | 'password'>) {
  // Log details without exposing sensitive information
  // ...
}
```

#Conclusion

By using TypeScript's utility types like Partial, Pick, and Omit, you can create more precise, maintainable, and flexible code. This not only improves the developer experience but also leads to a safer and more robust application. If you've been avoiding these tools, give them a try in your next project. You might be surprised at how much they can enhance your coding style!