Utility Types en TypeScript II: Pick, Omit, Exclude y Extract

Mientras que Partial, Required y Readonly modifican todas las propiedades de un tipo, los utility types de esta segunda parte operan de forma selectiva: Pick y Omit trabajan con las propiedades de un objeto, mientras que Exclude y Extract filtran los miembros de un union type. Conocerlos bien evita duplicar definiciones de tipos en el código de API.

Pick: seleccionar propiedades concretas

Pick<T, K> construye un tipo con solo las propiedades de T que aparecen en K. Es útil para exponer versiones reducidas de un tipo completo, como un perfil público que no incluye datos sensibles:

interface Usuario {
  id: number;
  nombre: string;
  email: string;
  passwordHash: string;
  rol: "admin" | "usuario";
  creadoEn: Date;
}

type PerfilPublico = Pick;
// { id: number; nombre: string }

type DatosAdmin = Pick;
// Las propiedades sensibles como passwordHash no aparecen

Omit: excluir propiedades

Omit<T, K> es el inverso de Pick: construye el tipo con todas las propiedades excepto las listadas en K. Cuando el conjunto de propiedades a conservar es grande y solo quieres eliminar unas pocas, Omit es más cómodo que Pick:

// En lugar de listar los 10 campos que sí quieres, excluyes el 1 que no
type UsuarioSinPassword = Omit;

// Payload para crear un usuario: sin id ni fecha (los genera el servidor)
type CrearUsuario = Omit;

Un patrón habitual con Omit es construir el tipo del payload PATCH a partir del tipo completo, eliminando los campos de solo lectura del servidor:

type PatchUsuario = Partial>;
// { nombre?: string; email?: string; rol?: "admin" | "usuario" }

Exclude: filtrar un union type

Exclude<T, U> elimina de un union type T los miembros que son asignables a U:

type StatusHTTP = 200 | 201 | 301 | 400 | 401 | 403 | 404 | 500;

type StatusError   = Exclude;
// 400 | 401 | 403 | 404 | 500

type StatusExito   = Exclude;
// 200 | 201 | 301

type SinString = Exclude;
// number | boolean

Extract: conservar solo los miembros que coinciden

Extract<T, U> hace lo contrario que Exclude: conserva solo los miembros de T que son asignables a U:

type SoloStrings = Extract;
// string | boolean

type StatusRedirección = Extract;
// 301 (los demás no están en StatusHTTP)

NonNullable: eliminar null y undefined

NonNullable<T> es una aplicación de Exclude que elimina null y undefined de un tipo. Es especialmente útil al limpiar resultados de funciones que pueden devolver null:

type Nullable = string | number | null | undefined;
type Limpio = NonNullable;
// string | number

function filtrarNulos(arr: (T | null | undefined)[]): NonNullable[] {
  return arr.filter((x): x is NonNullable => x != null);
}

const valores = [1, null, 2, undefined, 3];
const limpios = filtrarNulos(valores); // number[]

La combinación de Pick, Omit, Exclude, Extract y NonNullable cubre la mayoría de situaciones donde necesitas derivar un tipo a partir de otro sin repetirlo. El principio general es el mismo que en el código de aplicación: DRY aplicado al sistema de tipos.

Imagen: Pexels / Godfrey Atima

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP