Utility Types in TypeScript

· 5 min read · Updated March 7, 2026 · beginner
typescript utility-types types advanced

TypeScript provides a set of utility types that help you transform and manipulate existing types. These utility types are built into the TypeScript compiler and can dramatically improve your type definitions. In this tutorial, you’ll learn the most commonly used utility types and how to apply them in real-world scenarios.

Partial and Required

The Partial<T> utility type constructs a type with all properties of T set to optional. This is useful when you want to update an object partially.

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

// All properties are now optional
type PartialUser = Partial<User>;

// This is valid - we can provide only some properties
function updateUser(id: number, updates: PartialUser): void {
  console.log(`Updating user ${id}`, updates);
}

updateUser(1, { name: "Alice" }); // Only updating name
updateUser(1, { email: "alice@example.com", age: 30 }); // Multiple updates

Conversely, Required<T> makes all properties required, the opposite of Partial.

interface Config {
  host?: string;
  port?: number;
  ssl?: boolean;
}

const fullConfig: Required<Config> = {
  host: "localhost",
  port: 8080,
  ssl: true,
};

Pick and Omit

Pick<T, K> creates a new type by selecting specific properties K from type T.

interface Article {
  id: number;
  title: string;
  content: string;
  author: string;
  publishedAt: Date;
  status: "draft" | "published" | "archived";
}

// Only pick the fields we need for a preview
type ArticlePreview = Pick<Article, "id" | "title" | "author">;

const preview: ArticlePreview = {
  id: 1,
  title: "Understanding TypeScript Utility Types",
  author: "John Doe",
};

Omit<T, K> does the opposite—it creates a type by excluding specific properties K from T.

type ArticleWithoutContent = Omit<Article, "content">;

const articleSummary: ArticleWithoutContent = {
  id: 1,
  title: "Understanding TypeScript Utility Types",
  author: "John Doe",
  publishedAt: new Date(),
  status: "published",
};

Record

The Record<K, T> utility type constructs an object type whose property keys are K and values are T. It’s perfect for creating dictionaries or mapped types.

type Role = "admin" | "user" | "guest";

interface Permission {
  canRead: boolean;
  canWrite: boolean;
  canDelete: boolean;
}

const rolePermissions: Record<Role, Permission> = {
  admin: { canRead: true, canWrite: true, canDelete: true },
  user: { canRead: true, canWrite: true, canDelete: false },
  guest: { canRead: true, canWrite: false, canDelete: false },
};

function checkPermission(role: Role, action: keyof Permission): boolean {
  return rolePermissions[role][action];
}

console.log(checkPermission("admin", "canDelete")); // true
console.log(checkPermission("guest", "canWrite"));  // false

Extract and Exclude

Extract<T, U> extracts types from T that are assignable to U.

type T = Extract<"a" | "b" | "c" | "d", "a" | "c" | "f">;
// Result: "a" | "c"

type Numbers = Extract<string | number | boolean, number>;
// Result: number

// Practical example: extracting certain event types
type Event =
  | { type: "click"; x: number; y: number }
  | { type: "keydown"; key: string }
  | { type: "focus" }
  | { type: "blur" };

type MouseEvent = Extract<Event, { type: "click" }>;
// Result: { type: "click"; x: number; y: number }

Exclude<T, U> does the opposite—it removes types from T that are assignable to U.

type T = Exclude<"a" | "b" | "c" | "d", "a" | "c">;
// Result: "b" | "d"

type NotNull = Exclude<string | number | null | undefined, null | undefined>;
// Result: string | number

ReturnType and ParameterType

ReturnType<T> extracts the return type of a function type T.

function getUser() {
  return { id: 1, name: "Alice" };
}

type UserReturn = ReturnType<typeof getUser>;
// Result: { id: number; name: string }

function getUsers() {
  return [{ id: 1, name: "Alice" }, { id: 2, name: "Bob" }];
}

type UserList = ReturnType<typeof getUsers>;
// Result: { id: number; name: string }[]

ParameterType<T> (or Parameters<T>) extracts the parameter types of a function.

function createUser(name: string, age: number, email: string) {
  return { name, age, email };
}

type CreateUserParams = Parameters<typeof createUser>;
// Result: [string, number, string]

const params: CreateUserParams = ["Alice", 30, "alice@example.com"];
const user = createUser(...params);

Practical Example: API Response Handler

Here’s how you can combine utility types in a real-world scenario:

interface ApiResponse {
  id: number;
  title: string;
  body: string;
  userId: number;
  createdAt: string;
  updatedAt: string;
}

// We want a form that can partially update an article
type UpdateArticleForm = Partial<Pick<ApiResponse, "title" | "body">>;

// We want to display article summaries in a list
type ArticleSummary = Pick<ApiResponse, "id" | "title" | "createdAt">;

// We want to validate incoming API data
function validateArticle(data: unknown): data is Partial<ApiResponse> {
  if (typeof data !== "object" || data === null) return false;
  const obj = data as Record<string, unknown>;
  return (
    obj.title === undefined || typeof obj.title === "string"
  ) && (
    obj.body === undefined || typeof obj.body === "string"
  );
}

Summary

TypeScript’s utility types are powerful tools that let you transform and manipulate types with ease:

  • Partial/Required — Toggle property optionality
  • Pick/Omit — Select or exclude specific properties
  • Record — Create object types with specific keys and value types
  • Extract/Exclude — Filter union types
  • ReturnType/Parameters — Extract function type information

These utilities reduce boilerplate and make your type definitions more expressive and maintainable. In the next tutorial, we’ll explore decorators in TypeScript.