Utility Types in TypeScript
TypeScript provides utility types to help transform or create new types from existing ones.
These types are built into TypeScript and are extremely useful for making your code cleaner, more expressive, and easier to maintain. You might be aware about some and regularly using it while some from the list might be new to learn.
Below is a breakdown of key utility types with Definitions and examples. Added a summary table in the end, don't forget to read it.
Let's take User
type for reference as below:
interface User {
id: string;
name: string;
isAdmin: boolean;
age?: number;
}
1. Partial<Type>
Definition: Makes all properties of Type optional.
Use Case: When you want to create a version of a type where some or all properties might not be defined.
const payload: Partial<User> = { name: "John" }; // Valid ✅
2. Required<Type>
Definition: Makes all properties of Type required.
Use Case: To enforce that every property must be provided.
// Not Valid ❌
const user: Required<User> = { name: "John" };
// Valid ✅ (all properties provided)
const user: Required<User> = {
id: "1",
name: "John",
age: 34,
isAdmin: false
};
3. Readonly<Type>
Definition:: Makes all properties of Type readonly (cannot be reassigned).
Use Case: To create immutable objects.
const user: Readonly<User> = { id: "1", name: "John", isAdmin: false };
user.name = "Bob"; // Error: Cannot assign to 'name' because it is a read-only property.
4. Pick<Type, Keys>
Definition:: Constructs a type by picking a subset of properties from a given Type.
Use Case: To extract specific properties from a type.
const userPreview: Pick<User, "id" | "name"> = { id: "1", name: "John" };
5. Omit<Type, Keys>
Definition:: Constructs a type by omitting specific properties from a given Type.
Use Case: To exclude certain properties from a type.
const userDetails: Omit<User, "age" | "isAdmin"> = { id: "1", name: "John" };
You can see that we have achieved same underlying type using Pick and Omit. (Picking id
and name
is same as Omitting age
and isAdmin
from type User
)
6. Record<Keys, Type>
Definition:: Constructs a type with keys of Keys and values of Type.
Use Case: To create a dictionary-like object.
type UserRoles = 'ADMIN' | 'CUSTOMER' | 'SUPER_ADMIN'
// Valid ✅
const roleMatrix: Record<UserRoles, boolean> = {
'ADMIN': true,
'CUSTOMER': true,
'SUPER_ADMIN': false
}
// Not Valid ❌
const roleMatrix: Record<UserRoles, boolean> = {
'ADMIN': true,
'CUSTOMER': true,
'SUPER_ADMIN': false,
'MANAGER': true // Error: As MANAGER is not present in UserRoles
}
7. Exclude<Type, ExcludedUnion>
Definition:: Excludes from Type those types that are assignable to ExcludedUnion.
Use Case: To filter out specific types from a union.
type UserRoles = 'ADMIN' | 'CUSTOMER' | 'SUPER_ADMIN'
type AdminRoles = Exclude<UserRoles, 'CUSTOMER'> // remove the CUSTOMER from UserRoles
const role: AdminRoles = 'CUSTOMER' // Not Valid ❌
const role: AdminRoles = 'ADMIN' // Valid ✅
8. Extract<Type, Union>
Definition:: Extracts from Type those types that are assignable to Union.
Use Case: To filter specific types from a union.
type UserRoles = 'ADMIN' | 'CUSTOMER' | 'SUPER_ADMIN'
type AdminRoles = Extract<UserRoles, 'ADMIN' | 'SUPER_ADMIN'> // Only include 'ADMIN' & 'SUPER_ADMIN' from UserRoles
const role: AdminRoles = 'CUSTOMER' // Not Valid ❌
const role: AdminRoles = 'ADMIN' // Valid ✅
9. NonNullable<Type>
Definition:: Excludes null and undefined from Type.
Use Case: To ensure a type is not nullable.
type UserId = string | number | null | undefined;
// Valid ✅
const id1: UserId = '12'
const id2: UserId = 12
const id3: UserId = null
const id4: UserId = undefined
type NonNullId = NonNullable<UserId>
// Not Valid ❌
const id5: NonNullId = null; // Error: Type 'null' is not assignable to type 'NonNullId'
Pro Tip:
You can create your own NonNullable type using Exclude. Here is how it can be done.
type UserId = string | number | null | undefined;
type NonNullId = Exclude<UserId, null | undefined>
// Not Valid ❌
const id: NonNullId = null; // Error: Type 'null' is not assignable to type 'NonNullId'
10. ReturnType<Type>
Definition:: Constructs a type consisting of the return type of a function type.
Use Case: To infer and reuse function return types.
function getUser() {
return { id: "1", name: "John" };
}
type User = ReturnType<typeof getUser>; // { id: number; name: string }
11. Parameters<Type>
Definition:: Constructs a tuple (array) type of the parameters of a function type.
Use Case: To infer and reuse function parameter types. Gives the type of function parammets.
function updateUser(id: number, name: string) {}
type UpdateParams = Parameters<typeof updateUser>; // [number, string]
// Valid ✅
function updateBook(...params: UpdateParams) {} // params = (id: number, name: string)
updateBook(12, 'Atomic Habits')
Summary Table of Key Utility Types
You might be feeling there are so many utility types provided by TypeScript. Isn't it?
But no worries, this table will summarize all of them so that you can refer it anytime.
Utility Type | Purpose |
---|---|
Partial<Type> |
Makes all properties optional |
Required<Type> |
Makes all properties required |
Readonly<Type> |
Makes all properties readonly |
Pick<Type, K> |
Picks specific properties |
Omit<Type, K> |
Omits specific properties |
Record<K, T> |
Creates a dictionary-like type |
Exclude<T, U> |
Excludes types from a union |
Extract<T, U> |
Extracts types from a union |
NonNullable<T> |
Removes null and undefined
|
ReturnType<T> |
Gets the return type of a function |
Parameters<T> |
Gets the parameters of a function |
Closing Comments 👋
In this article, we learned various Utility Types provided by TypeScript and understood well with help of code snippets.
For any questions or suggestions, please feel free to comment below. 💬
If you find this article useful, share it with your friends and follow for regular update of such good articles. 🔗
Rushi Patel, Signing Off! 😊
Top comments (0)