TYPESCRIPT

TypeScript Utility Types: Syntax, Usage, and Examples

TypeScript utility types help you transform existing types without rewriting or duplicating code. These built-in tools simplify complex type operations and make your codebase more maintainable. With just a few keywords, you can make properties optional, remove them, pick certain ones, or create completely new type combinations.

How to Use TypeScript Utility Types

You apply TypeScript utility types directly to existing types or interfaces. The syntax usually follows a pattern like this:

type Modified = UtilityType<OriginalType, Parameters>;

Let’s look at the most useful utility types TypeScript offers.

Common Utility Types in TypeScript

Partial

Makes all properties of a type optional.

type User = {
  name: string;
  age: number;
};

type PartialUser = Partial<User>;

// Now this is valid:
const u: PartialUser = { name: "Alice" };

Use this when you’re only updating part of an object, like in a patch function.

Required

Makes all optional properties required.

type OptionalUser = {
  name?: string;
  age?: number;
};

type RequiredUser = Required<OptionalUser>;

const u: RequiredUser = { name: "Bob", age: 28 }; // Both fields now required

Readonly

Prevents reassignment of properties after initialization.

type User = {
  name: string;
  age: number;
};

const u: Readonly<User> = { name: "Carol", age: 22 };
// u.age = 23; // Error: Cannot assign to 'age'

Use this to protect values from accidental changes.

Pick

Creates a new type by selecting specific properties.

type User = {
  id: number;
  name: string;
  email: string;
};

type BasicUser = Pick<User, "id" | "name">;

Omit

The opposite of Pick. It excludes specified properties.

type BasicUser = Omit<User, "email">;

Record

Creates a type with a fixed set of property keys and the same value type for all.

type Scores = Record<string, number>;

const gameScores: Scores = {
  Alice: 90,
  Bob: 85,
};

This is helpful for objects with dynamic keys but consistent values.

Exclude

Removes specific members from a union.

type Roles = "admin" | "editor" | "guest";
type PublicRoles = Exclude<Roles, "admin">;

Extract

The opposite of Exclude. It keeps only the matching members.

type EditorRoles = Extract<Roles, "editor" | "guest">;

NonNullable

Removes null and undefined from a type.

type MaybeString = string | null | undefined;
type DefinitelyString = NonNullable<MaybeString>;

ReturnType

Gets the return type of a function.

function getAge(): number {
  return 30;
}

type Age = ReturnType<typeof getAge>; // number

Parameters

Extracts the parameter types of a function into a tuple.

function greet(name: string, age: number): void {}

type GreetArgs = Parameters<typeof greet>; // [string, number]

When to Use Utility Types in TypeScript

Use TypeScript utility types when you:

  • Want to avoid repeating type definitions.
  • Need to create flexible, reusable APIs.
  • Transform existing types in a safe, predictable way.
  • Work with forms, API payloads, or UI states that change over time.
  • Need to handle optional or readonly data structures.

Utility types that TypeScript provides can make your code easier to maintain and reduce room for human error.

Examples of Using Utility Types

Building Form State Types

type Product = {
  name: string;
  price: number;
  inStock: boolean;
};

type ProductFormState = Partial<Product>;

This lets you build a form where fields can be filled in gradually.

Creating Immutable Config Objects

type Config = {
  apiUrl: string;
  timeout: number;
};

const appConfig: Readonly<Config> = {
  apiUrl: "https://api.example.com",
  timeout: 5000,
};

// appConfig.timeout = 3000; // Error: Cannot assign

Modeling API Response with Omit

If your API returns data including fields you don’t want to expose on the frontend:

type FullUser = {
  id: number;
  name: string;
  password: string;
};

type PublicUser = Omit<FullUser, "password">;

You can now safely expose PublicUser in your components.

Learn More About TypeScript Utility Types

Custom Utility Types

You’re not limited to built-in types. You can define your own:

type Nullable<T> = { [P in keyof T]: T[P] | null };

This allows you to convert all properties of a type into nullable versions.

type Profile = {
  name: string;
  age: number;
};

type NullableProfile = Nullable<Profile>;

Deep Utility Types

TypeScript utility types only work on the first level of properties. For deeply nested types, use community tools or write recursive custom types. For example:

type DeepPartial<T> = {
  [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};

This allows you to make even nested properties optional.

Utility Types for Component Props

If you use frameworks like React, you’ll often create types based on props:

type ButtonProps = {
  label: string;
  onClick: () => void;
  disabled?: boolean;
};

type RequiredProps = Required<ButtonProps>;

You can also extract prop types from components with React.ComponentProps<typeof Button>.

Combining Utility Types

You can chain utility types to create exactly what you need:

type EditableUser = Partial<Omit<User, "id">>;

This makes all fields optional—except the one you left out.

Tips for Using Utility Type TypeScript Tools Effectively

  • Use utility types for fast prototyping and cleaner code.
  • Avoid deeply nested generics if you can simplify the base types.
  • Read the type signature! Knowing what utility types return helps you predict behavior.
  • When working with libraries like Redux or React Query, utility types are great for transforming API responses or state slices.

Best Practices

  • Use Partial for draft forms or patch endpoints.
  • Use Pick and Omit to reuse existing types safely.
  • Use Readonly when passing down props or shared config.
  • Avoid overcomplicating your types—just because you can nest utility types doesn’t mean you should.
  • Combine built-in and custom utility types to stay DRY and type-safe.

The TypeScript utility types built into the language give you superpowers for shaping data models. From building cleaner forms to extracting just the right fields from a backend API, utility types in TypeScript let you focus on logic—not boilerplate.

Learn TypeScript for Free
Start learning now
button icon
To advance beyond this tutorial and learn TypeScript by doing, try the interactive experience of Mimo. Whether you're starting from scratch or brushing up your coding skills, Mimo helps you take your coding journey above and beyond.

Sign up or download Mimo from the App Store or Google Play to enhance your programming skills and prepare for a career in tech.

You can code, too.

© 2025 Mimo GmbH