Typescript Made Easy - Part 1
Tags: typescript, webdev, programming, beginners
Published: 2023-02-20 11:10:24

## 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.
```typescript
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:
```typescript
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. 
```typescript
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`:
```typescript
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:
```typescript
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.
```typescript
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:
```typescript
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:
```typescript
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:
```typescript
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:
```typescript
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:
```typescript
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!

### Resources:

- [Typescript Type Challenges](https://github.com/type-challenges/type-challenges)
- [Typescript Docs](https://www.typescriptlang.org)
- [The Typescript Wizard](https://www.youtube.com/@mattpocockuk)