How does the TypeScript Partial type work?
The Partial<Type> type is a built-in TypeScript utility type that takes a Type and creates a new type with all Type's properties set to optional.
(I know it's a lot of types).
It is often used, when you need to update a few (but not all) properties from an existing object.
In this article, you will learn everything to know about the Partial utility type, as well as get real-life use cases for this type.
What is the Partial type?
The Partial type is used to simplify type generation when you need to make all the properties from a type optional.
Here is an example of the Partial type.
typescriptinterface IArticle {
content: string;
tags: string[];
category: string;
}
const updatedArticle: Partial<IArticle> = {
content: 'new content'
};
In this example, we take the interface IArticle and we create a new object called updatedArticle. That object accepts all the properties from the IArticle interface.
The Partial is particularly useful when you need to:
- Update some fields in an existing object.
- Mock some functions in your unit test.
- Pass constructor values to populate a new instance of the class.
The Partial built-in type was released in TypeScript version 2.1.
Other built-in types released in this version include:
3. The Readonly type.
What are some of the Partial type use cases?
Here are a few examples of the Partial type in real-life situations.
1. When you need to only update some fields in an existing object
typescriptinterface IArticle {
content: string;
tags: string[];
category: string;
}
const update = (article: Partial<IArticle>): void => {
// update the article here.
};
update({ content: 'new content' });
In this example, the update function accepts a parameter called article which is a Partial of the type IArticle. That way we can pass an object with only one field from the IArticle interface.
2. When you need to pass constructor values to populate a new instance of the class
typescriptclass Article {
public content!: string;
public tags!: string[];
public category!: string;
public constructor(data: Partial<Article>) {
Object.assign(this, data);
}
}
const article = new Article({
content: 'New content'
});
In that case, we use the Partial type to populate the Article class with values.
How to use the Partial type on nested objects?
To use the Partial type on a nested object you need to define a recursive helper type that will do the job for you.
typescripttype RecursivePartial<T> = {
[P in keyof T]?: RecursivePartial<T[P]>;
};
Read more: The keyof operator in TypeScript
Then, using this helper type, you recursively make all the properties of the new type optional.
typescriptinterface IPerson {
firstName: string;
lastName: string;
address: {
city: string;
country: string;
}
}
const updatePerson: RecursivePartial<IPerson> = {
address: {
city: 'Montreal'
},
firstName: 'Tim',
};
Have you noticed that I am using an interface with a type... Do you know why? I have written an extensive article about the differences between a type vs an interface in TypeScript, that will explain why and when to use which.
How to use the Partial type but require some properties?
To make some properties required in a new type, you can use a combination of the keyof keyword with the Partial and the Pick built-in type to create a new helper type.
typescripttype AtLeast<T, K extends keyof T> = Partial<T> & Pick<T, K>;
Then, using this helper type, it is very easy to require some properties.
typescriptinterface IPerson {
firstName: string;
lastName: string;
password: string
age: number;
}
type UpdatedPerson = AtLeast<IPerson, 'firstName'>;
const updatedPerson: UpdatedPerson = {
firstName: 'Tim'
};
In that example, only the firstName field is a required field, the rest of the fields are optional.
Conclusion
In conclusion, I very often (almost daily), use the Partial type, when I need to update some fields in an object and during unit testing.
Now that you've learned everything to know about this built-in type, please share this article with your coworkers and fellow developers.
Thank you for reading.