Getting friendly with Utility Types in TypeScript

Getting friendly with Utility Types in TypeScript

This article is intended for anyone who is trying to get to grips with the world of TypeScript.

This article will cover:

  • Utility Types 🥝
  • Lots of simple code examples 🪄

Article content
Photo by Any Lane:


In TypeScript, there are multiple built-in default types that we can use.

These are basically types that TypeScript has already created and so we don’t need to worry about creating them ourselves.

As always, examples are our friend because the more I write, the more likely I am to start talking about Jason Bateman or Jason Sudeikis. Oh, there we go.

Article content
Jason Bateman in Ozark

Utility type one: Partial<T>

Partial<T> is the same as adding ? to all the properties.

In a nutshell: Partial<T> makes all properties optional.

// simple interface example

interface A {
x: number;
y: number;
}

const example: A = {
x: 1,
y: 2,
}        

The examples above show us a simple interface example. The example below shows us how Partial<T> works.

Because Partial<T> makes all properties optional, we are free to choose which of the properties when we create a variable with this type, and we don’t get an error if we don’t use them all.

// Partial<T> example 

const partialExample: Partial<A> = {
x: 1,
}        

Utility type two: Required<T>

This is the reverse of Partial<T>

In a nutshell: it makes all optional properties of an interface required.

// simple interface example

interface B {
x?: number;
y?: number;
}

const example: B = {
x: 1,
}        

The examples above show a simple interface with all properties as optional. The example below shows how Required<T> works. It makes all of these properties required and will show an error if any of these properties are missing.

// Required<T> example 

const requiredExample: Required<B> = {
x: 2,
y: 4,
}        

Utility type three: Readonly<T>

In a nutshell: this is the same as Required<T> but it makes all the properties read only.

// simple interface example

interface C {
x: number;
y: number;
}        

Above, we have another simple interface example. Below we can see how Readyonly<T> works.

Because we have made readonlyExample a Readonly type, we are not able to modify these variables, as you can see in the example below.

Article content
Readonly<T>


Utility type four: Pick<T, K>

With Pick<T,K>, we can choose the properties that we want to use from another type/interface.

In a nutshell: we can create a new type with certain properties from another type/interface.

// simple interface example

interface D {
x: number;
y: number;
z: number;
}        

In the example above, we have another simple interface. Below, we can see the syntax for Pick<T,K>:

// Pick<T, K> example

type E = Pick<D, "x", | "z">         

Essentially, we are creating a new type E which only has the x and z properties from interface D (we've basically removed the y property).

If you hover over type E you can see the shape it has:

Article content
type


Utility type five: Omit<T, K>

This is the exact opposite of Pick<T, K>

In a nutshell: you remove the properties you don’t want to include in your new type/interface.

// Omit<T, K> example

type F = Omit<D, "y">         

Again, in the above example, we are using interface D and instead of picking the variables we want to use for type F, we are selecting the variables we would like to omit.

This means that type F would have the exact same shape as type E as you can see in the example below:

Article content
type


Utility type six: Exclude <T, U>

This is similar to Omit<T, K> but is used for Union types and not properties within types.

In a nutshell: it lets us exclude certain members from an already defined union type.


Refresher: Union types can be one of several types. For example, if a property can be a string OR a number.


Article content
Exclude<T, K>

Shows is a Union type and can be one of 3 values ("Ozark", ""Arrested Development", or "Ted Lasso").

JasonBatemanShows is a type created from the Shows type, but it omits the show Ted Lasso because (hopefully it’s common knowledge) he does not appear in this show. This would be Jason Sudeikis. Oh, great I’m doing it again.

Now, when we hover over JasonBatemanShows you should know what to expect:

Article content
Exclude<T, K>


Utility type seven: NonNullable<T>

The name pretty much explains this one.

In a nutshell: it removes all the null or undefined elements of a type.

// NonNullable<T> example

type G = string | string[] | undefined | null;
type I = NonNullable<G>;        

Above, you see that we have a Union type G which can be of type string, string[], undefined or null.

We can remove the undefined and null types with NonNullable<T>

Article content
NonNullable<T>


Utility type eight: Record <K, T>

In a nutshell: this is a shortcut for defining an object type with a specific key and value type.

This means you can narrow down your records by only accepting specific keys or types of keys.

// Record<K, T> example 

const thisIsARecord: Record<string, number> = {
apples: 10, oranges: 5}        

In the above example, we have created a simple Record type called thisIsARecord. This record takes string as the key and number as the value.

This type is good to use when you are mapping and only want to allow certain types for keys or values. For example, the key should always be a string and the value should also be a number.

Let’s see one more example, to help it stick:

Article content
Union type example

Above, we have extended our Shows Union type.

Below, we have created a new Record type which takes the Shows type as its key and boolean as its value.

// Record<K, T> example

type recordExample = Record<Shows, boolean>        

This means that the key has to be either: "Ozark", "Arrested Development", "Ted Lasso" or "Stranger Things", and the value can only be true or false.

// Record<K, T> example

const jasonBatemanShows: recordExample = {
"Ozark": true,
"Arrested Development": true,
"Ted Lasso": false,
"Stranger Things": false,
}
        

This protects us from making any typos or adding incorrect values, which could be a pain to debug later:

Article content
TypeScript error example

TypeScript also helps us out and offers us only the valid values we can use for this property:

Article content
Intellisense from TypeScript

We all love IntelliSense, right? 🤤

Now go ahead and create some Utility types of your own! I think you'll find it surprisingly fun :)

To view or add a comment, sign in

More articles by Sammy-Jo Wymer, MSc

Insights from the community

Explore topics