Typescript Utility Types
Arthur Vincent Simon
Posted on March 7, 2020
Introduction
As I was starting to get serious in learning Typescript, I came across a set of utility types the proved useful when I tried to refactor the types in the codebase of the company that we are in.
Before that point, I assumed that for reusing types code, I have to make granular types and export them to each type that need them in their fields.
For example, if I have a Person
type that I am using in a Parent
type or a Child
type, I have to create it, export it out and use it. Of course this is just a simple example. When we get to having a lot of type sharing across the components, then we can see how it can become unwieldy to import the type every time we try to use that type.
Enter the utility types. These utilities aim to remove the problem of the redundantly defining and importing each functions. I want to go over some of them that I find useful.
Utilities
Pick
When we want to reuse or “pick” out some properties inside a type, we would us Pick
. Very useful as it saves me time having to create new types just to copy the properties of existing types.
interface Workstation {
CPU: string
GPU: string
RAM: string
monitor: string
keyboard: monitor
}
type Computer = Pick<Workstation, 'CPU' | 'GPU' | 'RAM'>
Partial
When we want to make the properties of a certain type optional, we use Partial
. Useful when refactoring.
interface Car {
wheels: string
windshield: string
body: string
doors: string
}
type Car2 = Partial<Car>
Required
On the other hand, if we want to make the properties of a certain type to be required, we use Required
. Useful to force your types based on external library types.
interface OptionalParams {
a?: string
b?: string
}
type RequiredParams = Required<OptionalParams>
Record
Very useful when constructing types for configurations.
interface Person {
name: string
}
type Family = ‘father’ | ‘mother’ | ‘sibling’
const myFamily: <Family, Person> = {
father: { name: ‘John’ },
mother: { name: ‘Jane’ },
sibling: { name: ‘Joe’ }
}
Omit
Very useful to get a cut down version of a type
interface Article {
title: string;
summary: string;
text: string;
}
type ArticlePreview = Omit<Article, text>;
const todo: ArticlePreview = {
title: ‘The misadventures of Joe’,
summary: ‘Joe goes out of his way to explore. Will he survive?’
};
Exclude
Basically a “complement” of two sets
type Toys = Exclude<“knife” | “ball” | “xylophone”, “knife”>; // “ball” | “xylophone”
Extract
Basically an “intersection” of two sets
type Vehicle = Extract<“skateboard” | “car” | “motorbike”, “car” | “motorbike” | “wheelchair”>; // “car” | “motorbike”
Conclusion
In my continuous improvement of learning Typescript and trying to incorporate it to my code, I found using these utility types more. As long as I don’t go overboard with them, it helps make my code more concise and understandable. I hope you guys find them useful too.
Posted on March 7, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 28, 2024