Q13 of 38 · TypeScript

What are TypeScript's built-in utility types, and which are most useful in test automation?

TypeScriptMidtypescriptutility-typespartialpickomitrecordgenerics

Short answer

Short answer: `Partial<T>` makes all properties optional. `Required<T>` makes all required. `Pick<T, K>` and `Omit<T, K>` select/exclude properties. `Record<K, V>` maps keys to a value type. `Readonly<T>` prevents reassignment. `ReturnType<F>` and `Parameters<F>` extract function types. These eliminate redundant type duplication.

Detail

TypeScript ships a library of generic utility types that transform existing types without duplicating their definitions.

Structure modifiers:

  • Partial<T>: all properties become optional — used for update payloads where only some fields change
  • Required<T>: all optional properties become required
  • Readonly<T>: all properties become readonly
  • Mutable<T>: (not built-in; often defined as a custom type) removes readonly

Property selectors:

  • Pick<T, K>: produces a new type with only the properties named in K
  • Omit<T, K>: produces a new type without the properties named in K — common for dropping id from a create payload

Record and Mapping:

  • Record<K, V>: all keys of type K map to values of type V — great for lookup tables in tests

Function type extractors:

  • ReturnType<F>: extracts the return type of a function — lets you type test data to match real return values without duplicating the interface
  • Parameters<F>: extracts parameter types as a tuple
  • ConstructorParameters<C>, InstanceType<C>

Conditional utilities:

  • NonNullable<T>: removes null and undefined from T
  • Exclude<T, U>, Extract<T, U>: filter union types

// EXAMPLE

interface User {
  id: number;
  name: string;
  email: string;
  role: "admin" | "viewer";
}

// Partial — update payload
type UserUpdate = Partial<User>; // all optional

// Omit — create payload (no id yet)
type CreateUser = Omit<User, "id">;

// Pick — just the display fields
type UserSummary = Pick<User, "id" | "name">;

// Record — test lookup table
const rolePermissions: Record<User["role"], string[]> = {
  admin: ["read", "write", "delete"],
  viewer: ["read"],
};

// ReturnType — type test data to match function output
async function fetchUser(): Promise<User> { /* ... */ }
type FetchedUser = Awaited<ReturnType<typeof fetchUser>>;

// NonNullable
type MaybeUser = User | null | undefined;
type DefiniteUser = NonNullable<MaybeUser>; // User

// WHAT INTERVIEWERS LOOK FOR

Knowing at least 6 built-in utility types with usage examples. `Omit` for create payloads and `ReturnType` for matching function output are the most practically relevant for test code. `Record` for lookup tables in tests is a bonus.

// COMMON PITFALL

Manually duplicating a type to remove one property instead of using `Omit`. If the source type changes, the copy drifts — Omit stays in sync automatically.