Menu

Utility types en TypeScript: la lista completa con ejemplos

Todos los utility types integrados de TypeScript en un solo sitio: Partial, Required, Readonly, Pick, Omit, Record, Exclude, Extract, NonNullable, Parameters, ReturnType, Awaited, los tipos de strings y más, cada uno con una descripción de una línea y un ejemplo ejecutable.

Esta página incluye editores ejecutables: edita, ejecuta y ve el resultado al instante.

Los utility types son tipos genéricos integrados en TypeScript que convierten un tipo en otro. En lugar de escribir un segundo tipo User con todos los campos opcionales, escribes Partial<User>; en lugar de copiar tres campos, Pick<User, "id" | "name">. Son globales, así que no hace falta importarlos.

Cuando User cambia, los cuatro tipos derivados lo siguen. La librería estándar de TypeScript (lib.es5.d.ts) declara 22 utility types. Las secciones siguientes los recogen todos, agrupados según el tipo de tipo con el que trabajan, con un enlace a la página detallada cuando la hay.

Tipos objeto: Partial, Required, Readonly, Pick, Omit, Record

Utility typeQué haceEjemplo
Partial<T>hace opcionales todas las propiedadesPartial<User> para los datos de una actualización
Required<T>hace obligatorias todas las propiedades (quita ?)Required<Config> después de aplicar los valores por defecto
Readonly<T>hace readonly todas las propiedadesReadonly<State>
Pick<T, K>conserva solo las claves KPick<User, "id" | "name">
Omit<T, K>quita las claves KOmit<User, "password">
Record<K, V>un tipo objeto con claves K y valores VRecord<"en" | "de", string>

Required<T> es lo contrario de Partial<T>; la página de Partial trata los dos, incluido el undefined explícito que deja pasar un spread como este.

Tipos unión: Exclude, Extract, NonNullable

Utility typeQué haceEjemplo
Exclude<U, M>quita los miembros de la unión que se pueden asignar a MExclude<"a" | "b" | "c", "a"> es "b" | "c"
Extract<U, M>conserva los miembros de la unión que se pueden asignar a MExtract<string | number, number> es number
NonNullable<T>quita null y undefinedNonNullable<string | null> es string

Estos tres trabajan sobre uniones, no sobre objetos. Esa es la diferencia clave con Pick y Omit, que reciben un tipo objeto y una lista de sus claves.

Tipos de funciones y clases: Parameters, ReturnType y más

Utility typeQué haceEjemplo
ReturnType<F>el tipo de retorno de un tipo funciónReturnType<typeof createStore>
Parameters<F>los tipos de los parámetros como una tuplaParameters<typeof fetchPage>[0]
ConstructorParameters<C>los parámetros del constructor de una clase como una tuplaConstructorParameters<typeof Point>
InstanceType<C>el tipo de la instancia que crea un constructorInstanceType<typeof Point>
ThisParameterType<F>el tipo del parámetro this de una funciónThisParameterType<typeof greet>
OmitThisParameter<F>el tipo función sin su parámetro thisel tipo de greet.bind(obj)
ThisType<T>fija el tipo de this dentro de los métodos de un objeto literalse usa con noImplicitThis en APIs tipo builder
NoInfer<T>impide que un parámetro de tipo se infiera desde esta posiciónfallback: NoInfer<C>

typeof createOrder hace falta porque estos utility types reciben un tipo, y createOrder es un valor. Con las clases pasa lo mismo: typeof Point es el tipo del constructor, mientras que Point a secas como tipo ya significa el tipo de la instancia.

NoInfer controla de dónde saca su tipo un genérico:

Sin NoInfer, TypeScript inferiría C a partir de los dos argumentos y lo ampliaría a "red" | "green" | "blue", así que aceptaría la errata del valor por defecto.

Tipos de strings: Uppercase, Lowercase, Capitalize, Uncapitalize

Utility typeQué haceEjemplo
Uppercase<S>pasa a mayúsculas un tipo literal de stringUppercase<"get"> es "GET"
Lowercase<S>lo pasa a minúsculasLowercase<"GET"> es "get"
Capitalize<S>pone en mayúscula el primer carácterCapitalize<"name"> es "Name"
Uncapitalize<S>pone en minúscula el primer carácterUncapitalize<"Name"> es "name"

Estos cuatro están integrados en el compilador en lugar de estar escritos en TypeScript, y son más útiles dentro de los template literal types, como `on${Capitalize<E>}` para nombres de handlers de eventos.

Promesas: Awaited

Utility typeQué haceEjemplo
Awaited<T>el tipo que obtienes con await, desenvolviendo promesas anidadasAwaited<Promise<Promise<number>>> es number

Awaited<ReturnType<typeof fn>> es la forma estándar de nombrar el tipo del resultado de una función async sin declararlo aparte.

Combinar utility types

Los utility types se anidan. Algunas combinaciones aparecen tan a menudo que vale la pena sabérselas de memoria:

Un utility type anidado se lee de dentro hacia fuera: Readonly<Pick<Post, "id" | "title">> primero conserva dos propiedades y luego las hace de solo lectura. Con las mismas piezas se construye un helper PartialBy que hace opcionales solo algunas claves; la página de Partial lo desarrolla.

Los utility types no hacen nada en ejecución

Todos los utility types se borran al compilar. Un valor tipado como Omit<User, "password"> puede seguir llevando una contraseña en ejecución si el objeto del que salió la tenía:

El tipo solo limita lo que tu código puede leer. Para quitar un campo de los datos, sácalo con una desestructuración como en las últimas líneas, y para impedir modificaciones en ejecución usa Object.freeze, no Readonly. Los tipos integrados son mapped types y conditional types de una línea, así que con las mismas herramientas puedes escribir los tuyos.

Preguntas frecuentes

¿Qué son los utility types en TypeScript?

Tipos genéricos que vienen con TypeScript y transforman otros tipos: Partial<T> hace opcionales todas las propiedades, Pick<T, K> conserva algunas propiedades, ReturnType<F> obtiene el tipo de retorno de una función, etc. Están declarados en la librería estándar, así que los usas sin importar nada.

¿Tengo que importar los utility types?

No. Partial, Omit, Record, ReturnType y los demás son tipos globales de los archivos de librería integrados en TypeScript. Escribe Partial<User> donde quieras; no hace falta ningún import ni ningún paquete npm.

¿Qué utility types trae TypeScript?

22, todos declarados en lib.es5.d.ts: Partial, Required, Readonly, Pick, Omit, Record, Exclude, Extract, NonNullable, Parameters, ConstructorParameters, ReturnType, InstanceType, ThisParameterType, OmitThisParameter, ThisType, NoInfer, Awaited, Uppercase, Lowercase, Capitalize y Uncapitalize.

¿Los utility types cambian los objetos en tiempo de ejecución?

No. Solo describen tipos y se borran del JavaScript de salida. Omit<User, "password"> no elimina ninguna propiedad password, y Readonly<T> no congela nada. Para cambiar el objeto real, escribe el código: una desestructuración con rest, Object.freeze, etc.

¿Puedo escribir mis propios utility types?

Sí. Los integrados son TypeScript normal: la mayoría son mapped types o conditional types de una línea en lib.es5.d.ts. type Nullable<T> = { [K in keyof T]: T[K] | null } es un utility type propio escrito de la misma forma.

Coddy programming languages illustration

Aprende a programar con Coddy

COMENZAR