Lesson 15 of 20

Utility Types

Partial, Required, Readonly

TypeScript provides built-in utility types that transform existing types. These are incredibly useful for common patterns.

Example
interface User {
  name: string;
  email: string;
  age: number;
}

// Partial — all properties optional
type UpdateUser = Partial<User>;
const update: UpdateUser = { name: "Alice" }; // OK

// Required — all properties required
type FullUser = Required<User>;

// Readonly — all properties readonly
type FrozenUser = Readonly<User>;
const user: FrozenUser = { name: "Bob", email: "b@b.com", age: 30 };
// user.name = "Alice"; // Error: readonly

Pick, Omit, Record

These utility types let you create new types by selecting or excluding properties from existing types.

Example
interface User {
  id: number;
  name: string;
  email: string;
  password: string;
}

// Pick — select specific properties
type PublicUser = Pick<User, "id" | "name" | "email">;

// Omit — exclude specific properties
type SafeUser = Omit<User, "password">;

// Record — create object type with specific key/value types
type Scores = Record<string, number>;
const grades: Scores = { math: 95, english: 88 };

type UserRoles = Record<"admin" | "user" | "guest", string[]>;

Extract, Exclude, NonNullable

These utility types work with union types to filter and transform them.

Example
type AllTypes = string | number | boolean | null | undefined;

// Exclude — remove types from union
type Primitives = Exclude<AllTypes, null | undefined>;
// string | number | boolean

// Extract — keep only matching types
type Strings = Extract<AllTypes, string>;
// string

// NonNullable — remove null and undefined
type Defined = NonNullable<AllTypes>;
// string | number | boolean

// ReturnType — extract function return type
function fetchUser() {
  return { id: 1, name: "Alice" };
}
type UserResult = ReturnType<typeof fetchUser>;
// { id: number; name: string }