🔷 TypeScript Q17 / 101

Explain Pick and Omit utility types.

AI-Powered Answer ✓ Answered

TypeScript provides powerful utility types to help manipulate and transform existing types. Among the most commonly used are `Pick` and `Omit`, which allow developers to create new types by selecting or excluding properties from an existing type, respectively. They are invaluable for type safety and code reusability.

1. Pick<Type, Keys>

Pick<Type, Keys> constructs a type by picking the set of properties Keys (a union of string literals) from Type. It allows you to select only the properties you need from a larger interface or type.

typescript
interface User {
  id: number;
  name: string;
  email: string;
  isActive: boolean;
}

// Create a new type with only 'id' and 'name'
type UserSummary = Pick<User, 'id' | 'name'>;

const user1: UserSummary = {
  id: 1,
  name: 'Alice',
};

// This would cause a type error:
// const user2: UserSummary = {
//   id: 2,
//   name: 'Bob',
//   email: 'bob@example.com' // Property 'email' does not exist on type 'UserSummary'.
// };

In this example, UserSummary is derived from User but only includes the id and name properties. Attempting to assign properties not present in UserSummary will result in a compile-time error, ensuring type safety.

2. Omit<Type, Keys>

Omit<Type, Keys> constructs a type by taking all properties from Type and then removing Keys (a union of string literals). It's the inverse of Pick, allowing you to exclude specific properties from an existing type.

typescript
interface Product {
  id: string;
  name: string;
  price: number;
  description: string;
  createdAt: Date;
  updatedAt: Date;
}

// Create a new type without 'id', 'createdAt', and 'updatedAt'
type ProductCreationPayload = Omit<Product, 'id' | 'createdAt' | 'updatedAt'>;

const newProduct: ProductCreationPayload = {
  name: 'Laptop',
  price: 1200,
  description: 'Powerful and lightweight laptop.',
};

// This would cause a type error:
// const invalidProduct: ProductCreationPayload = {
//   id: 'p123', // Property 'id' does not exist on type 'ProductCreationPayload'.
//   name: 'Tablet',
//   price: 500,
//   description: 'Portable tablet.',
// };

Here, ProductCreationPayload is created by excluding the id, createdAt, and updatedAt properties from the Product interface. This is useful for defining types for API request bodies where certain properties are generated by the server and should not be provided by the client.

When to use them?

Pick is ideal when you need to define a new type that represents a *subset* of properties from an existing, larger type. Common use cases include defining types for: * Displaying partial data (e.g., a table row showing only a few columns). * API responses that return only specific fields. * Simplified views or components that only need a few properties of a complex object.

Omit is best used when you want to define a new type that is almost identical to an existing type, but *lacks* a few specific properties. Common use cases include: * Defining request payloads where properties like id, createdAt, updatedAt are generated by the server. * Creating "draft" types where certain mandatory fields are temporarily optional or omitted until a later stage. * Removing sensitive information from a type for specific contexts.

Conclusion

Both Pick and Omit are fundamental utility types in TypeScript, empowering developers to create more precise, reusable, and type-safe code. They promote the DRY (Don't Repeat Yourself) principle by allowing you to derive new types from existing ones with minimal effort, significantly enhancing maintainability and reducing errors in large applications.