Una guía rápida y práctica de los Utility Types de TypeScript, explicados con ejemplos simples y sin vueltas, para escribir menos código y tipar mucho mejor.
Publicado por

Si usás TypeScript todos los días, seguramente ya te cruzaste con cosas como Partial, Pick, Omit o Record.
Y si no, tranqui: te estás perdiendo joyitas que te hacen escribir menos código y evitar quilombos innecesarios.
Los Utility Types son como esos atajos que te sabés en el teclado y te cambian la vida. No son magia, pero te permiten transformar tipos como si fueran piezas de Lego.
En este artículo te muestro los más útiles (los que realmente vas a usar), explicados sin vueltas y con ejemplos claros.
Partial<T> — Hacé que todas las propiedades sean opcionalesCuando tenés un objeto gigante y querés permitir actualizaciones parciales, este tipo te salva.
Antes (dolor):
1type UserUpdate = {2 name?: string;3 email?: string;4 age?: number;5};Después (felicidad):
1type User = {2 name: string;3 email: string;4 age: number;5};6
7type UserUpdate = Partial<User>;Listo. Nada más que decir.
Lo que era un embole pasa a ser una línea.
Required<T> — Lo contrario de PartialConvierte TODAS las propiedades en obligatorias.
1type User = {2 name?: string;3 email?: string;4};5
6type StrictUser = Required<User>;Ahora StrictUser te obliga a mandar todo.
Muy útil para validaciones internas donde no querés medias tintas.
Readonly<T> — Evitá que te rompan el objetoIdeal cuando no querés que un objeto cambie nunca más.
1type Config = {2 apiKey: string;3 theme: string;4};5
6const config: Readonly<Config> = {7 apiKey: "123",8 theme: "dark",9};10
11config.theme = "light"; // ❌ ErrorPerfecto para configuraciones que no deberían mutar.
Pick<T, K> — Elegí solo las propiedades que te sirvenImaginá que tenés un tipo enorme, pero necesitás solo 2 campos.
Antes armabas otro tipo a mano… pero no hace falta.
1type User = {2 id: string;3 name: string;4 email: string;5 age: number;6};7
8type UserPreview = Pick<User, "id" | "name">;Boom. Solo lo que necesitás. Nada más.
Omit<T, K> — Todo menos estoEs el “anti Pick”.
1type UserWithoutEmail = Omit<User, "email">;Muy útil cuando querés mandar un objeto al frontend sin exponer algo sensible.
Record<K, T> — Tu colección tipada, sin dolor de cabezaSi querés un objeto tipo diccionario, este es EL utility type.
1type Roles = "admin" | "user" | "guest";2
3const permissions: Record<Roles, boolean> = {4 admin: true,5 user: true,6 guest: false,7};Con esto evitás:
Exclude<T, U> — Eliminá tipos de una unión1type Status = "loading" | "success" | "error";2
3type WithoutError = Exclude<Status, "error">;Extract<T, U> — Lo opuesto: quedate solo con los compatibles1type OnlyErrors = Extract<Status, "error">;NonNullable<T> — Chau null, chau undefined1type MaybeString = string | null | undefined;2
3type SafeString = NonNullable<MaybeString>; // solo stringEsto reduce MUCHOS bugs, especialmente en funciones.
Porque escribir tipos a mano es:
Y TypeScript ya te da todo hecho.
Lo mejor es que combinan entre sí, por ejemplo:
1type UserSafePreview = Readonly<Pick<User, "id" | "name">>;Tipo pequeño, seguro y sin mutaciones.
Perfecto.
Los Utility Types son una de esas cosas que ignorás hasta que las usás… y después no querés vivir sin ellas.
Te hacen escribir menos, equivocarte menos y pensar más en la lógica y menos en la burocracia del tipado.
Si usás TypeScript y no estás metiendo estos utilities en tu día a día… amigo, te estás complicando solo.