Learning Guides
Menu

Built-in Utility Types

2 min readEffective TypeScript

Built-in Utility Types

TypeScript includes a rich set of utility types. These let you transform existing types instead of duplicating them.

Item 86: Partial, Required, and Readonly

TYPESCRIPT
interface User {
  id: string;
  name: string;
  email: string;
}
 
type UserDraft = Partial<User>;
type UserStrict = Required<User>;
type UserReadonly = Readonly<User>;

Use Partial for updates, Required for creation, and Readonly for immutable views.

Item 87: Pick and Omit for View Models

TYPESCRIPT
type UserPreview = Pick<User, "id" | "name">;
type UserWithoutEmail = Omit<User, "email">;

Perfect for API responses and UI models.

Item 88: Record for Dictionaries

TYPESCRIPT
type UserById = Record<string, User>;

This is often clearer than index signatures.

Item 89: Exclude and Extract

TYPESCRIPT
type Status = "idle" | "loading" | "success" | "error";
type NonError = Exclude<Status, "error">;
type OnlyError = Extract<Status, "error">;

Item 90: NonNullable

TYPESCRIPT
type MaybeUser = User | null | undefined;
type UserOnly = NonNullable<MaybeUser>;

Item 91: Parameters, ReturnType, ConstructorParameters

TYPESCRIPT
function createUser(name: string, email: string) {
  return { id: crypto.randomUUID(), name, email };
}
 
type Args = Parameters<typeof createUser>;
type CreatedUser = ReturnType<typeof createUser>;
TYPESCRIPT
class Service {
  constructor(
    public url: string,
    public timeout = 1000,
  ) {}
}
 
type ServiceArgs = ConstructorParameters<typeof Service>;

Item 92: InstanceType

TYPESCRIPT
type ServiceInstance = InstanceType<typeof Service>;

Item 93: Awaited for Async Values

TYPESCRIPT
async function fetchUser() {
  return { id: "1", name: "Alice" };
}
 
type User = Awaited<ReturnType<typeof fetchUser>>;

Item 94: String Utility Types

TYPESCRIPT
type EventName = `on${Capitalize<"click" | "hover">}`; // onClick | onHover
type Lower = Lowercase<"Hello">; // 'hello'

Scenario: Typed Form Updates

TYPESCRIPT
type FormState = {
  name: string;
  email: string;
  subscribed: boolean;
};
 
function updateForm(state: FormState, changes: Partial<FormState>) {
  return { ...state, ...changes };
}

Key Takeaways

  1. Use utility types to avoid duplication.
  2. Partial and Required are essential for updates vs creation.
  3. Pick and Omit create view models quickly.
  4. Parameters and ReturnType keep types in sync with functions.
  5. String utility types are great for generated keys.

Next: type guards and assertions.