The Partial
keyword in Typescript has many uses, but when is actually a good use case for using it?
Well I’ve got a few quick ones so let’s dive in!
Extending types to reduce maintenance
Familiar with the DTO pattern? No? If not, this section is definitely for you!
Popularized by Java – at least I am quite sure it was – the DTO pattern describes a Data Transfer Object. I have found the DTO pattern to be incredibly useful when working with Typescript, because it fully utilizes a powerful concept of interfaces: inheritance.
Yes yes, I’m getting there! Here’s why that matters.
Say we have a User
class/entity that have certain required attributes, but is not necessarily instantiated with them. That could be because you have a “User Invite” or an “Inactive User” concept going on in your codebase.
So let’s say you wanted to edit the user, but you can’t really do that now right, since your User
is defined with certain required attributes that you don’t necessarily want to submit (again) on an update request, such as id
.
Here’s the solution for you!
export interface IUserEditDTO extends Partial<User> {}
And just for good measure, if you’re inheriting directly from a class, extends
wont work like this, so instead you should define a type
:
export type IUserEdit = Partial<User>
And voilá! You don’t have more maintenance, but you now have a much more flexible type that you can use when updating a user.
If the increased flexibility isn’t your cup of tea and you prefer specifying things, here’s another pattern you could use:
export interface IUserLogin extends Pick<User, 'email' | 'password'>
Now you have type definitions for more (or less) specific types of User, without having to write everything all over again.
Going even further, making it simpler yet
At work, I manage about ~8 User interfaces that (almost) all inherit from the same IUser
interface, making it incredibly easy to extend, narrow and maintain all of them, simply by managing one base class. We have several user actions that have delicate API endpoints and managing types like this reduces a lot of complexity.
But, you can actually make it even easier!
Lately I have been playing around with the satisfie
s keyword that I highly recommend you start using.
Coupling satisfies
with clever use of Partial
, Pick
and Exclude
you can make it very far without creating more maintenance for yourself!
And if you wanted to go even crazier you could look into something like phero. Phero is a library that allows your frontend to ‘read’ your type definitions from your backend, further minimizing the amount of maintenance you have to do for types!
I think this is an incredibly powerful tool.
As I round it off though, I want to give a full disclaimer: I have not yet played around with phero and have no practical experience with it. I just know of it, and I can see it looks promising.
But perhaps I will know more about it in a future post 🙂
Become a typescript hero
I’m sending occasional newsletters about once a week on new articles that will help you grow from zero to typescript-hero.
Sign up below to receive the newsletter!