Typescript utility types - partial, pick, omit y required

En TypeScript, Partial, Pick , Omit y Required son utility types que permiten crear nuevos tipos basados en otros, pero con ciertas modificaciones en sus propiedades. Son útiles para manejar estructuras de objetos de manera flexible sin duplicar tipos.

1. Partial<T>

Partial convierte todas las propiedades de un tipo en opcionales (undefined o el tipo original). Esto es útil cuando quieres crear un objeto que no necesita definir todas las propiedades de un tipo existente.

Ejemplo:

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

const updateUser = (user: Partial<User>) => {
  // Puedo pasar un objeto con algunas propiedades del tipo User
  console.log(user);
};

updateUser({ name: "John" }); // Esto es válido, ya que name es opcional con Partial
updateUser({ age: 25 });      // También válido
  • En este ejemplo, Partial<User> hace que las propiedades name, age y email sean opcionales. Por lo tanto, puedes pasar un objeto que tenga solo algunas propiedades de User.

2. Pick<T, K>

Pick crea un nuevo tipo basado en el tipo original T, pero solo selecciona un conjunto específico de propiedades K. Este tipo es útil cuando solo necesitas trabajar con algunas propiedades de un objeto.

Ejemplo:

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

type BasicUserInfo = Pick<User, 'name' | 'email'>;

const getUserInfo = (user: BasicUserInfo) => {
  console.log(user);
};

getUserInfo({ name: "Alice", email: "alice@example.com" }); // Válido
// getUserInfo({ name: "Alice", age: 25 }); // Error: 'age' no es parte de BasicUserInfo
  • Aquí, Pick<User, 'name' | 'email'> crea un tipo que solo tiene las propiedades name y email de User. Otras propiedades como age o address quedan fuera.

3. Omit<T, K>

Omit es lo opuesto a Pick: crea un nuevo tipo basado en T pero excluyendo un conjunto de propiedades K. Es útil cuando quieres trabajar con un objeto sin algunas propiedades.

Ejemplo:

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

type UserWithoutAddress = Omit<User, 'address'>;

const createUser = (user: UserWithoutAddress) => {
  console.log(user);
};

createUser({ name: "Bob", age: 30, email: "bob@example.com" }); // Válido
// createUser({ name: "Bob", address: "123 Street" }); // Error: 'address' no es parte de UserWithoutAddress
  • En este ejemplo, Omit<User, 'address'> crea un tipo basado en User, pero excluye la propiedad address, así que cualquier objeto de este tipo no puede incluir la propiedad address.

Resumen

  • Partial<T>: Convierte todas las propiedades de T en opcionales.
    • Ejemplo: Partial<User> convierte { name: string } en { name?: string }.
  • Pick<T, K>: Crea un nuevo tipo con solo las propiedades de T especificadas en K.
    • Ejemplo: Pick<User, 'name' | 'email'> crea un tipo con solo name y email.
  • Omit<T, K>: Crea un nuevo tipo que excluye las propiedades de T especificadas en K.
    • Ejemplo: Omit<User, 'address'> crea un tipo sin la propiedad address.

En TypeScript, Required<T> es otro utility type que hace que todas las propiedades de un tipo sean obligatorias, es decir, convierte las propiedades opcionales en requeridas.

4. Required<T>

Required toma un tipo que podría tener algunas propiedades opcionales y las convierte en propiedades obligatorias (todas las propiedades deben ser definidas).

Ejemplo:

interface User {
  name: string;
  age?: number;  // Opcional
  email?: string;  // Opcional
}

type FullUser = Required<User>;

const createUser = (user: FullUser) => {
  console.log(user);
};

// Este objeto ahora debe incluir todas las propiedades, incluso las que eran opcionales
createUser({ name: "Alice", age: 25, email: "alice@example.com" }); // Válido
// createUser({ name: "Alice" }); // Error: Falta age y email, que ahora son requeridos
  • En este ejemplo, Required<User> convierte las propiedades opcionales (age y email) de User en requeridas. Por lo tanto, al crear un objeto de tipo FullUser, debes proporcionar valores para todas las propiedades.

Diferencia con Partial

  • Partial<T> hace que todas las propiedades sean opcionales, lo cual es útil cuando no necesitas pasar todas las propiedades de un objeto.
  • Required<T> hace que todas las propiedades sean obligatorias, lo cual es útil cuando necesitas garantizar que todas las propiedades de un objeto estén definidas.

Resumen de Required

  • Required<T>: Convierte todas las propiedades de T en obligatorias (requeridas), incluso si originalmente eran opcionales.
    • Ejemplo: Required<User> convierte { name: string; age?: number } en { name: string; age: number }.

Estos utility types (Partial, Pick, Omit, Required) son muy útiles para adaptar tipos a diferentes escenarios y hacer que tu código sea más flexible y reutilizable en TypeScript.