Build Your own Types From Scratch
Are you ready to take your Typescript skills to the next level? In this Series of Blog Posts, we will see how to build our own custom Typescript types from scratch. Typescript types are the building blocks of your code, and they allow you to create more robust and flexible applications. Whether you're a beginner or an experienced developer, learning how to create custom types will help you write better code and improve your productivity. So, what are you waiting for? Let's dive in and explore 10 different typescript types that will supercharge your development process!
The Pick
Type
Have you ever needed to create a new type that only includes a subset of the properties from an existing type? If so, the Pick
type in Typescript has got you covered. With just a few lines of code, you can create a new type that selects the properties you need and leaves the rest behind.
type Pick<T, K extends keyof T> = { [P in K]: T[P] }
Under the hood, Pick is implemented using a generic type alias that takes two type parameters: T
(the original type) and K
(a union of keys from T). The resulting type has the same keys as K
, but their values come from the corresponding properties in T
. This can be incredibly useful when working with large data structures or defining props for React components.
The Readonly
Type
The Readonly
type in Typescript creates a new type where all properties of an object are readonly. This can be useful when you need to ensure that an object's properties can't be modified after they're initialized. Here's the code for Readonly
under the hood:
type Readonly<T> = {readonly [K in keyof T]: T[K]}
The Readonly
type uses a mapped type to iterate over the keys in T
and create a new type that has the same keys, but all of their values are readonly. This can make your code more robust and less error-prone, especially when working with large or complex data structures. This can be useful in many contexts, such as when defining configuration objects, constants, or state variables.
The First
Type
The First
type in Typescript is a generic type that takes an array type T
and returns the type of its first element. This type is useful when you need to work with arrays and want to ensure that the first element has a certain type. There are two ways to implement First in Typescript.
The first way is to simply use T[0]
to get the type of the first element.
type First<T extends any[]> = T[0]
However, this approach has a flaw, when the array is empty, T[0] will return undefined, which is not ideal.
To avoid this, we can use the second approach: T extends [] ? never : T[0]
. This will check if the type of T
is an empty array. If it is, it returns never
, which is a type that cannot be instantiated. If it is not empty, it returns the type of the first element, which is T[0]
. Here's the code for updated First
:
type First<T extends any[]> = T extends [] ? never : T[0];
The Length
Type
The Length
type in Typescript is a generic type that takes an array type T
and returns the length of that array as a number. This can be useful when you want to ensure that a given array has a certain number of elements or when you want to perform operations based on the length of an array. Here's the code for Length under the hood:
type Length<T extends readonly any[]> = T['length']
The Length
type uses a type alias that takes a single type parameter T
, which extends an array of any readonly types. Then, it simply returns the 'length'
property of T
. This is a concise way to get the length of an array in Typescript, which can save you time and improve your code's readability.
The Exclude
Type
Have you ever needed to create a new type that excludes some types from another type? If so, the Exclude
type in TypeScript can be a powerful tool. With a concise implementation, you can create a new type that removes the undesired types.
type Exclude<T, U> = T extends U ? never : T;
The Exclude
type uses conditional types to check whether each element of T
is assignable to U
. If it is, the type never is returned, which represents a type that can never be instantiated. If it is not assignable to U
, the original type T
is returned.
The Omit
Type
The Omit
type in Typescript is similar to Pick
, but it creates a new type that excludes a subset of properties from an existing type. This can be useful when you need to create a new type that has most of the properties of an existing type, but with some of them omitted.
Here is the implementation of Omit under the hood:
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
As you can see, Omit
uses Pick
and Exclude
to select a subset of properties from T
and exclude them from the resulting type. The resulting type has all the properties of T
, except for the properties listed in K
.
The Required
Type
The Required
type in Typescript creates a new type where all properties of an object are required. This can be useful when you need to ensure that an object has all the required properties before it can be used. Here's the implementation of Required
under the hood:
type Required<T> = { [P in keyof T]-?: T[P] };
Required
uses a mapped type to iterate over the keys in T
and create a new type that has the same keys, but all of their values are required. The -?
syntax in the mapped type makes each property required. This can make your code more robust and less error-prone, especially when working with objects that require certain properties to be present.
The Partial
Type
The Partial
type in Typescript creates a new type where all properties of an object are optional. This can be useful when you need to create an object that doesn't require all the properties to be set initially. Here's the implementation of Partial
under the hood:
type Partial<T> = { [P in keyof T]?: T[P] };
Partial
uses a mapped type to iterate over the keys in T
and create a new type that has the same keys, but all of their values are optional. The ?
syntax in the mapped type makes each property optional. This can be useful when working with configuration objects, where not all properties are required, or when dealing with optional props in React components.
The Record
Type
The Record
type in Typescript creates a new type where the keys and values have a specific type. This can be useful when you need to define an object with a fixed set of keys and corresponding types.
Here's the implementation of Record under the hood:
type Record<K extends keyof any, T> = { [P in K]: T };
Record takes two type parameters: K
(the keys) and T
(the values). It uses a mapped type to iterate over the keys in K
and create a new type that has the same keys, but all of their values are of type T
. This can be useful when working with dictionaries or maps, or when you need to define a fixed set of keys for a particular object.
The Nullable
Type
The Nullable
type in TypeScript allows you to create a new type that includes the original type as well as null and undefined. Here's how it's implemented under the hood:
type Nullable<T> = T | null | undefined;
The Nullable
type is implemented as a simple union type that includes the original type T
, as well as null
and undefined
. This can be useful when you want to allow a property to be null
or undefined
, but still want to maintain the original type.
Conclusion
Learning how to build TypeScript types can take your coding skills to the next level! We've covered ten powerful types that can make your code more flexible and robust. Whether you're using Pick
or Omit
, these types can save you time and make your code more readable.
Don't forget to leave a comment if you liked the blog or you have some questions.
Follow us, and share your experiences with these types in the comments.
I will be exploring another set of TypeScript types in the next part of this blog series. And based on your feedback we can improve how we present these explanations to you
Thanks for reading, and happy coding!
Top comments (0)