Skip to main content
eLearner.app
Module 4 · Lesson 2 of 28/14 in the course~15 min
Module lessons (2/2)

Utility Types

TypeScript provides several global utility types to facilitate common type transformations. These types are generic and allow you to declaratively build new types from existing ones.

The four most commonly used utility types are:

1. Partial<T>

Makes all properties of a type T optional. This is extremely useful for update/patch functions where the caller might only supply a subset of fields:

TS
interface User {
  id: number;
  name: string;
  email: string;
}

// All properties of User become optional: { id?: number; name?: string; email?: string; }
type UserUpdate = Partial<User>;

2. Readonly<T>

Makes all properties of a type T readonly. Any attempt to reassign a property will trigger a compile-time compiler error:

TS
interface Point {
  x: number;
  y: number;
}

const p: Readonly<Point> = { x: 10, y: 20 };
// p.x = 5; // Error: cannot assign to 'x' because it is a read-only property

3. Pick<T, Keys>

Creates a type by selecting only a specific set of keys (represented by a string union) from the type T:

TS
interface Article {
  id: number;
  title: string;
  content: string;
  views: number;
}

// Selects only 'title' and 'views': { title: string; views: number; }
type ArticlePreview = Pick<Article, 'title' | 'views'>;

4. Omit<T, Keys>

Creates a type by removing a specific set of keys from the type T. It is the dual of Pick:

TS
interface Product {
  id: number;
  name: string;
  price: number;
  secretVendorCode: string;
}

// Removes 'secretVendorCode': { id: number; name: string; price: number; }
type PublicProduct = Omit<Product, 'secretVendorCode'>;

5. Record<Keys, Type>

Creates an object type whose property keys are Keys and whose property values are Type. It is extremely useful for mapping keys to values, representing dictionaries or hash tables (key-value maps):

TS
type Page = 'home' | 'about' | 'contact';

interface PageInfo {
  title: string;
}

// Creates a dictionary with keys 'home' | 'about' | 'contact' and values PageInfo
const nav: Record<Page, PageInfo> = {
  home: { title: 'Home Page' },
  about: { title: 'About Us' },
  contact: { title: 'Contact Us' },
};

Try it yourself

Exercise 1: Profile Update with Partial

Exercise#ts.m4.l2.e1
Attempts: 0Loading…

Complete the updateProfile function that accepts an original profile (Profile) and an updates object (updates) where all fields of Profile are optional. It must return a new Profile object combining the original properties with the updates.

Loading editor…
Show hint

Use the Partial<Profile> utility type for the updates parameter, and the spread operator to merge the objects: { ...original, ...updates }.

Solution available after 3 attempts

Exercise 2: Removing Sensitive Fields with Omit

Exercise#ts.m4.l2.e2
Attempts: 0Loading…

Given the UserAccount type, define a type alias named SafeUser that omits the sensitive passwordHash property.

Loading editor…
Show hint

Use type SafeUser = Omit<UserAccount, 'passwordHash'>; to omit the specified field.

Solution available after 3 attempts

Exercise 3: Public Config with Pick and Readonly

Exercise#ts.m4.l2.e3
Attempts: 0Loading…

Given the AppConfig type, define a type alias named PublicConfig that is a read-only (Readonly) version containing only the apiEndpoint and port properties selected using Pick.

Loading editor…
Show hint

Use type PublicConfig = Readonly<Pick<AppConfig, 'apiEndpoint' | 'port'>>;

Solution available after 3 attempts

Exercise 4: User Registry with Record and Readonly

Exercise#ts.m4.l2.e4
Attempts: 0Loading…

Given a User interface with fields id: number and name: string, create a type ReadOnlyUser that makes all fields in User readonly. Then, create a type UserRegistry that represents a dictionary where the key is a string (e.g., string id) and the value is a ReadOnlyUser.

Loading editor…
Show hint

Use Readonly<User> to define ReadOnlyUser, and Record<string, ReadOnlyUser> for the registry.

Solution available after 3 attempts