Dataslope logoDataslope

Utility Types

Master TypeScript's built-in utility types and learn how they're implemented.

TypeScript ships with a rich set of utility types — pre-built generic types that perform common transformations. You've already glimpsed a few (like Partial and Pick). Now that you understand mapped and conditional types, we'll tour the full lineup and demystify how each is implemented.

These utilities aren't magic. They're all built from the primitives you've learned: mapped types, conditional types, keyof, indexed access, and infer. By the end of this chapter, you'll see that you could write them yourself — and you'll know when to reach for them in real code.


Object Transformation Utilities

These types reshape object types by adding, removing, or filtering properties.

Partial<T>

Makes all properties of T optional.

Code Block
TypeScript 5.7

Use case: Update functions where you only want to specify changed fields:

Code Block
TypeScript 5.7

Implementation:

type Partial<T> = { [K in keyof T]?: T[K] };

A simple mapped type that adds the ? modifier to each property.


Required<T>

Makes all properties of T required (removes optionality).

Code Block
TypeScript 5.7

Use case: Enforcing complete objects after optional construction or partial validation.

Implementation:

type Required<T> = { [K in keyof T]-?: T[K] };

The -? modifier removes optionality.


Readonly<T>

Makes all properties of T readonly.

Code Block
TypeScript 5.7

Use case: Immutable data structures, preventing accidental mutations in pure functions.

Implementation:

type Readonly<T> = { readonly [K in keyof T]: T[K] };

Adds readonly to each property.


Pick<T, K>

Constructs a type by picking a set of properties K from T.

Code Block
TypeScript 5.7

Use case: Creating focused view types or API responses that expose only a subset of fields.

Implementation:

type Pick<T, K extends keyof T> = { [P in K]: T[P] };

Maps over the chosen keys K (which must be valid keys of T) and includes only those.


Omit<T, K>

Constructs a type by omitting a set of properties K from T.

Code Block
TypeScript 5.7

Use case: Removing sensitive or internal fields before sending data to clients.

Implementation:

type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;

First, Exclude<keyof T, K> produces the keys not in K. Then Pick selects those. We'll cover Exclude next.


Record<K, T>

Constructs an object type with keys K and values of type T.

Code Block
TypeScript 5.7

Use case: Building lookup maps or dictionaries with known keys.

Implementation:

type Record<K extends keyof any, T> = { [P in K]: T };

A mapped type that iterates over K (a union of keys) and assigns type T to each.


Union Filtering Utilities

These types filter or extract members from unions.

Exclude<UnionType, ExcludedMembers>

Removes types from UnionType that are assignable to ExcludedMembers.

Code Block
TypeScript 5.7

Use case: Removing unwanted cases from a union, such as filtering out null or undefined.

Implementation:

type Exclude<T, U> = T extends U ? never : T;

A distributive conditional type: for each member of T, if it extends U, return never (which vanishes from the union); otherwise, keep it.


Extract<UnionType, Union>

Extracts from UnionType those types that are assignable to Union.

Code Block
TypeScript 5.7

Use case: Selecting a subset of a union that matches a constraint, like "all string literals" or "all object types."

Implementation:

type Extract<T, U> = T extends U ? T : never;

The opposite of Exclude: keep members of T that do extend U.


NonNullable<T>

Removes null and undefined from T.

Code Block
TypeScript 5.7

Use case: Narrowing types after you've checked for null/undefined, or enforcing non-null guarantees.

Implementation:

type NonNullable<T> = T extends null | undefined ? never : T;

Filters out null and undefined using a distributive conditional.


Function Utilities

These types extract information from function types.

ReturnType<T>

Extracts the return type of a function type T.

Code Block
TypeScript 5.7

Use case: Deriving the return type of a function without duplicating the annotation, especially useful with complex inferred returns.

Implementation:

type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;

Uses infer to capture the return type from the function signature.


Parameters<T>

Extracts the parameter types of a function type T as a tuple.

Code Block
TypeScript 5.7

Use case: Capturing the argument list for wrapper functions or generic higher-order functions.

Implementation:

type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;

Uses infer to capture the parameter tuple.


ConstructorParameters<T>

Extracts the parameter types of a constructor function type.

Code Block
TypeScript 5.7

Use case: Factory functions or dependency injection where you need to mirror constructor signatures.

Implementation:

type ConstructorParameters<T extends abstract new (...args: any) => any> = T extends abstract new (...args: infer P) => any ? P : never;

Similar to Parameters, but for constructor signatures.


InstanceType<T>

Extracts the instance type of a constructor function type.

Code Block
TypeScript 5.7

Use case: Referring to the instance type when you only have the constructor (e.g., in factory patterns).

Implementation:

type InstanceType<T extends abstract new (...args: any) => any> = T extends abstract new (...args: any) => infer R ? R : any;

Uses infer to capture the return type of the constructor (the instance).


ThisParameterType<T>

Extracts the type of the this parameter from a function type (or unknown if there is none).

Code Block
TypeScript 5.7

Use case: Working with functions that rely on a specific this context (common in OOP or event handlers).

Implementation:

type ThisParameterType<T> = T extends (this: infer U, ...args: any[]) => any ? U : unknown;

Uses infer to capture the this parameter.


Promise and Async Utilities

Awaited<T>

Recursively unwraps a Promise (or nested promises) to get the final resolved type.

Code Block
TypeScript 5.7

Use case: Getting the resolved type of async functions or deeply nested promises.

Implementation (simplified):

type Awaited<T> = T extends Promise<infer U> ? Awaited<U> : T;

Recursively unwraps Promise layers using infer.


Putting It All Together

Let's combine several utilities to build a type-safe API response handler:

Code Block
TypeScript 5.7

Challenge: Implement MyPick<T, K>

Challenge
TypeScript 5.7
MyPick<T, K>

The standard library provides Pick<T, K>, which constructs a type by selecting only properties K from T. Implement your own version, MyPick<T, K>, using a mapped type.

Hint: Map over K (not keyof T) and use indexed access T[P] to get each property's type.


Challenge: Implement MyExclude<T, U>

Challenge
TypeScript 5.7
MyExclude<T, U>

Implement MyExclude<T, U>, which removes members of T that are assignable to U.

Hint: Use a distributive conditional type that returns never for excluded members.


Multiple Choice: Utility Type Implementation

QuestionSelect one

Which utility type is implemented with this code?

type Mystery<T> = { [K in keyof T]-?: T[K] };

Partial<T>

Required<T>

Readonly<T>


Multiple Choice: ReturnType Inference

QuestionSelect one

Given:

function fetchUser(): Promise<{ id: number; name: string }> {
return Promise.resolve({ id: 1, name: "Alice" });
}
type Result = ReturnType<typeof fetchUser>;

What is Result?

{ id: number; name: string }

Promise<{ id: number; name: string }>

string


Summary

TypeScript's utility types are powerful shortcuts for common type transformations:

  • Object transformers: Partial, Required, Readonly, Pick, Omit, Record
  • Union filters: Exclude, Extract, NonNullable
  • Function introspection: ReturnType, Parameters, ConstructorParameters, InstanceType, ThisParameterType
  • Async unwrapping: Awaited

None of these are magic. They're all built from mapped types, conditional types, and infer. Now that you've seen their implementations, you can write your own utilities tailored to your domain.


Next: keyof, typeof & Template Literals — lifting values into types and building string-based type systems.

On this page