-
Notifications
You must be signed in to change notification settings - Fork 0
Utility Types
To understand what are utility types and partials, let's assume a simple example where we have:
- A user type defined as below
type User = { id: number; name: string; password: string; };
- A function to update an user, where we should be passing only the properties that should be updated, which should receive the parameters
idandupdateDataconst updUser = (id: number, updateData) => { /* update logic */ };
- A function to add an user, where we should be passing only required properties necessary to create an user, such as, in this case, the
nameand thepassword
const addUser = (newUser) => {
/* add logic */
};As we have seen before, if we try to provide just the properties we wish to change when working with object types into TypeScript, this will show us some typechecking warnings, even though the code is executed as expected.
With the knowledge we have so far, there would be thee possible ways of handling these warnings:
- Setting the type of the argument
updateDatatoany(as we already discussed - this is not advised when we are going to move to production) - Setting the type of the argument
updateDatatouser(but that would require us to pass a whole user object and not only the information to be updated) - Create a new type,
UpdateUserwith the same properties of typeUser, but setting all of them as opitional (this would generate bad practice, since we'd be making duplicated code when it's not necessary)
So the question is, what is the best way of solving this problem? That is where utility types and partials come into.
- Utility types take other types as parameter and return a new type, with some changes to made to it
- Utility types are built-in to TypéScript and allow to perform commonly-neded modifications to existing types
- Utility types use the Generics syntax represented by a pair of angle brackets (
<>)
The Partial utility type is responsible for modifying an already existing type and setting all is properties as optional.
This is basically the same as the 3rd possible way discussed above for fixing our type checking warnings, but without creating manually a new type and repating unnecessary code.
This is how it would look like on our example:
type UpdateUser = Partial<User>
const updUser = (id:number, updateData: UdpateUser) = {
/* update logic */
}The Omit utility type is responsible for taking an existing type AND a string (or union of strings) with a set of property names, while returning a new type with the properties declared on the type being removed from it.
This works similar to the Partial type:
const addUser = (newUser: Omit<User, 'id'>) = {
/* add logic */
}Note
It's part of good practices to make use of utility types declaration inline if we intend to use that specific type just once in our code.
Those notes were written while watching the tutorial videos while taking the classes from the online course Learn TypeScript on Scrimba.
Because english is not my mother language, they can contain some typos and everything written here is based on my understanding about the discussed topics and may not be 100% accurate.
If you want the full course, support the instructor by buying their course on Scrimba.
- Home
- Introduction
- Introduction to TypeScript
- The Pizza Application
- Move to TypeScript
- Defensive Coding
- Typing variables
- Typing Pizza App: part 1
- Custom types
- Typing Pizza App: part 2
- Nested Object types
- Optional Properties
- Typing Pizza App: part 3
- Array Types
- Typing Pizza App: part 4
- Literal Types
- Unions
- Typing Pizza App: part 5
- Typing Pizza App: part 6
- Typing Pizza App: part 7
- Returning Types
- Typing Pizza App: part 8
- Any Type
- Typing Pizza App: part 9
- Utility Types
- Typing Pizza App: part 10
- Generics
- Typing Pizza App: part 11