Skip to content
JL

Home

About

Blog

Contact

Shop

Portfolio

Privacy

TOS

Click to navigate

  1. Home
  2. Joshua R. Lehman's Blog
  3. Mastering TypeScript Utility Types

Table of contents

  • Share on X
  • Discuss on X

Related Articles

Basic Types in TypeScript
TypeScript
9m
Nov 23, 2025

Basic Types in TypeScript

TypeScript's type system starts with fundamental building blocks: primitive types like string, number, and boolean, along with arrays and type annotations. Understanding these basic types is essential for writing type-safe code. This comprehensive guide walks you through each primitive type, shows you how to use type annotations effectively, and teaches you best practices for working with arrays and basic data structures in TypeScript.

#TypeScript#Types+5
Template Literal Types in TypeScript
TypeScript
9m
Aug 2, 2026

Template Literal Types in TypeScript

Template literal types bring JavaScript's template literal syntax to the type level. They let you construct new string literal types by combining existing ones — the same way a template literal assembles a string at runtime, but resolved entirely at compile time.

#Template Literal Types#String Manipulation Types+5
Indexed Access Types in TypeScript
TypeScript
7m
Jul 26, 2026

Indexed Access Types in TypeScript

Indexed access types use the T[K] syntax to look up property types — the same bracket notation you use at runtime, but at the type level. They let you extract any type that lives inside another type without duplicating it.

#Indexed Access Types#TypeScript Type Lookup+5
Ask me anything! 💬

© Joshua R. Lehman

Full Stack Developer

Crafted with passion • Built with modern web technologies

2026 • All rights reserved

Contents

  • Introduction to Utility Types
  • Partial<T>
  • Required<T>
  • Pick<T, K>
  • Omit<T, K>
  • Record<K, T>
  • Readonly<T>
  • Best Practices
  • Common Use Cases
  • Next Steps
TypeScript

Mastering TypeScript Utility Types

February 1, 2026•3 min read
Joshua R. Lehman
Joshua R. Lehman
Author
TypeScript Utility Types
Mastering TypeScript Utility Types

Mastering TypeScript Utility Types#

TypeScript's utility types are built-in type transformations that help you manipulate and create new types from existing ones. They're powerful tools that can significantly reduce boilerplate and improve type safety in your applications.

Introduction to Utility Types

Utility types are generic types that take existing types and transform them in useful ways. They're part of TypeScript's standard library and can be used without any additional imports.

Partial T

Partial<T> makes all properties of T optional:

interface User {
  id: number;
  name: string;
  email: string;
}
 
// All properties become optional
type PartialUser = Partial<User>;
 
// Now we can create objects with just some properties
const updateUser: PartialUser = {
  name: "Alice Cooper",
};

This is particularly useful for update operations where you only need to provide some fields.

Required T

Required<T> makes all properties of T required (opposite of Partial):

interface UserPreferences {
  theme?: "light" | "dark";
  notifications?: boolean;
  newsletter?: boolean;
}
 
// All properties become required
type MandatoryPreferences = Required<UserPreferences>;
 
const prefs: MandatoryPreferences = {
  theme: "dark",
  notifications: true,
  newsletter: false,
};

Pick T K

Pick<T, K> creates a type by picking specific properties from T:

interface Product {
  id: number;
  name: string;
  price: number;
  description: string;
  category: string;
}
 
// Pick only name and price
type ProductSummary = Pick<Product, "name" | "price">;
 
const summary: ProductSummary = {
  name: "Laptop",
  price: 999.99,
};

Omit T K

Omit<T, K> creates a type by omitting specific properties from T:

interface User {
  id: number;
  name: string;
  password: string;
  email: string;
}
 
// Omit sensitive password field
type PublicUser = Omit<User, "password">;
 
const publicUser: PublicUser = {
  id: 1,
  name: "Alice",
  email: "[email protected]",
  // password is not allowed here
};

Record K T

Record<K, T> creates a type with keys of type K and values of type T:

// Create an object with string keys and number values
type Scores = Record<string, number>;
 
const examScores: Scores = {
  Alice: 95,
  Bob: 87,
  Charlie: 92,
};
 
// Or with specific keys
type Status = "pending" | "approved" | "rejected";
type StatusMessages = Record<Status, string>;
 
const messages: StatusMessages = {
  pending: "Your request is being reviewed",
  approved: "Your request has been approved",
  rejected: "Your request has been rejected",
};

Readonly T

Readonly<T> makes all properties of T readonly:

interface Config {
  apiUrl: string;
  timeout: number;
  retries: number;
}
 
type ReadonlyConfig = Readonly<Config>;
 
const config: ReadonlyConfig = {
  apiUrl: "https://api.example.com",
  timeout: 5000,
  retries: 3,
};
 
// config.timeout = 1000;
// Error: Cannot assign to 'timeout' because it is a read-only property

Best Practices

  • Use utility types to avoid duplicating type definitions
  • Combine utility types for more complex transformations
  • Prefer Pick over Omit when you need fewer properties, as it's more explicit
  • Use Partial for update operations where not all fields are required
  • Leverage Record for dictionary-like structures

Tip: You can combine utility types for more complex transformations:

// Make only specific properties optional
type UserUpdate = Partial<Pick<User, "name" | "email">>;

Common Use Cases

  1. API Responses: Use Omit to remove sensitive fields from responses
  2. Form Validation: Use Partial for form state where not all fields are filled
  3. Configuration Objects: Use Readonly for config that shouldn't change
  4. Data Transformation: Use Pick to create simplified versions of complex objects
  5. Dictionary Structures: Use Record for key-value mappings

Next Steps

Next, learn about advanced type manipulation techniques including conditional types, mapped types, and template literal types to further enhance your TypeScript skills.