Combining TypeScript utility types

I'm a full-stack developer from South Africa 🇿🇦. I love writing about JavaScript, HTML and CSS.
Search for a command to run...

I'm a full-stack developer from South Africa 🇿🇦. I love writing about JavaScript, HTML and CSS.
No comments yet. Be the first to comment.
Most of you know me for my consistency, a golden arrow in my blog series. I've written 1000 articles in 1008 days! Almost an article a day, and my honeymoon was the only holiday I ever took. I'm super proud of this achievement; it has been a fantasti...

It's not the first time I'll be talking about community. I think it's an essential aspect of any successful tool. This shows in my previous explorations of Astro, Medusa, and now Vendure as well. All these products thrive in a super open, welcoming, ...

The cool part about Vendure is how easy it is to set up and how abstract each layer is. Basically, we get the following elements: External database Server Worker Admin UI Frontend While this is amazing, it also brings a bit of complexity when it co...

The previous article looked at customizing Vendure on a data and process level. In this article, we'll look at customizing emails, as they are often a big part of a webshop system. We'll be looking at two different layers of customization for customi...

Even though Vendure is a pretty significant project out of the box, in some cases, we might want to go in and modify some elements to work to our specific use case. In this article, I'll take a high-level look at some elements we can customize within...

By now, we had a basic introduction to some of the utility types of TypeScript.
However, the real power unleashes when you combine them.
When we used the partial and required types, you might have noticed that they have one downside: they affect all properties.
By combining them with pick and omit, we can ensure only specific fields are affected.
Let's take a look at how this would work.
Disclaimer: This article is for TypeScript beginners. We have not yet covered Generics, so nothing will use generics in this article.
Let's take the following example interface:
interface User {
id?: number;
firstname: string;
lastname: string;
age?: number;
}
What if we want to make just the id required but leave the age optional?
Depending on our end use-case, we have two options here.
First, let's say all other fields can be optional, but the id must be set.
We can choose to make a new type combining Partial and Required.
It will looks like this:
type LoggedUser = Partial<User> & Required<Pick<User, 'id'>>;
What we say here is:
Pick only the id field to make requiredLoggedUser type.We end up with a type with three optional fields: firstname, lastname and age and one required field: id.
But, in some cases, this is not exactly what we wanted, as we don't want the first and last name to be optional.
We could, of course, include them in the required statement, but that would defeat the purpose.
In that case we can write the following type:
type LoggedUser = Required<Pick<User, 'id'>> & Omit<User, 'id'>;
What this one does:
id field by picking it from the userLoggedUser typeWe have three required fields in this scenario: firstname, lastname, and id. And one optional field, the age.
As you can see, using a combination of utility types is really where they shine. You can make crazy combinations, and once we dive into generics, we can turn these into re-usable types!
Thank you for reading my blog. Feel free to subscribe to my email newsletter and connect on Facebook or Twitter