Utility Types in TypeScript: A Detailed Explanation

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 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 = { name: "John" }; // Valid ✅ 2. Required Definition: Makes all properties of Type required. Use Case: To enforce that every property must be provided. // Not Valid ❌ const user: Required = { name: "John" }; // Valid ✅ (all properties provided) const user: Required = { id: "1", name: "John", age: 34, isAdmin: false }; 3. Readonly Definition:: Makes all properties of Type readonly (cannot be reassigned). Use Case: To create immutable objects. const user: Readonly = { id: "1", name: "John", isAdmin: false }; user.name = "Bob"; // Error: Cannot assign to 'name' because it is a read-only property. 4. Pick 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 = { id: "1", name: "John" }; 5. Omit Definition:: Constructs a type by omitting specific properties from a given Type. Use Case: To exclude certain properties from a type. const userDetails: Omit = { 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 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 = { 'ADMIN': true, 'CUSTOMER': true, 'SUPER_ADMIN': false } // Not Valid ❌ const roleMatrix: Record = { 'ADMIN': true, 'CUSTOMER': true, 'SUPER_ADMIN': false, 'MANAGER': true // Error: As MANAGER is not present in UserRoles } 7. Exclude 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 // remove the CUSTOMER from UserRoles const role: AdminRoles = 'CUSTOMER' // Not Valid ❌ const role: AdminRoles = 'ADMIN' // Valid ✅ 8. Extract 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 // Only include 'ADMIN' & 'SUPER_ADMIN' from UserRoles const role: AdminRoles = 'CUSTOMER' // Not Valid ❌ const role: AdminRoles = 'ADMIN' // Valid ✅ 9. NonNullable 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 // 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 // Not Valid ❌ const id: NonNullId = null; // Error: Type 'null' is not assignable to type 'NonNullId' 10. ReturnType 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; // { id: number; name: string } 11. Parameters 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; // [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 wi

Feb 18, 2025 - 18:21
 0
Utility Types in TypeScript: A Detailed Explanation

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

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

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

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

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

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

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

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

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

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

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

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 Makes all properties optional
Required Makes all properties required
Readonly Makes all properties readonly
Pick Picks specific properties
Omit Omits specific properties
Record Creates a dictionary-like type
Exclude Excludes types from a union
Extract Extracts types from a union
NonNullable Removes null and undefined
ReturnType Gets the return type of a function
Parameters Gets the parameters of a function

Closing Comments