Awaited
Se trata del utility type mas recientemente agregado (al momento de escribir este articulo) ya que se incorporó en la version 4.5 de TypeScript.Su principal objetivo es modelar el comportamiento de operaciones asíncronas o en promesas irresolubles.
declare function MiPromesa<T>(value: T): T | Promise<T> | PromiseLike<T>;
async function algo(): Promise<[number, number]> {
const result = await Promise.all([MiPromesa(100), MiPromesa(200)]);
// Error!
//
// [number | Promise<100>, number | Promise<200>]
//
// is not assignable to type
//
// [number, number]
return result;
}
Omit
Permite construir un Type a partir de otro, seleccionando todas las propiedades por defecto y removiendo-omtiendo solo aquellas que se indiquen explícitamente.Ahora procedemos a generar un nuevo productoEn este caso nosotros queremos crear un producto pasando como parametro el nombre y su valor pero no queremos establecer un id ya que esta tarea es responsabilidad del sistema y no de nosotros (Por ejemplo si este servicio se conecta con una base de datos)
Para solucionar este problema podríamos crear un elemento que contenga únicamente aquellos atributos que el usuario deba diligenciar, en este caso solo "nombre" y "valor". Aquí es donde entra en juego omit:Con esto ya tendríamos solucionado el problema pues ahora con este nuevo tipo podemos indicar que el nuevo producto debe tener todos los atributos EXCEPTO el id. Ahora modificamos un poco el método "crearProducto":
// creamos una interfaz llamada Producto y deifnimos algunas propiedades
interface Producto {
id: number;
nombre: string;
valor: number;
}
// creamos una clase que se encarga de gestionar los productos:
class ManipularProductos{
productos: Producto[] = [];
obtenerProductos(): Producto[]{ return this.productos };
crearProducto(data: Poducto){
this.productos.push(data);
return data;
}
}
const servicio = new ManipularProductos();
const productos = servicio.obtenerProductos();
const nuevoProducto = {
nombre: 'barra de Chocolate',
valor: 5000
}
// si tratamos de crear un nuevo producto con el elemento "nuevoProducto" como argumento
// obtendremos un error ya que el metodo "crearProducto" espera un elemento de tipo "Producto"
// y en nuestro caso no contamos con el atributo id por lo tanto no es válido:
servicio.crearProducto(nuevoProducto);
/**
* Argument of type '{nombre: string; valor: number; }' is not assignable to parameter of type 'Producto'
* Type '{nombre: string; valor: number; }' is missing the following properties from type 'Producto': id
*/
Para solucionar este problema podríamos crear un elemento que contenga únicamente aquellos atributos que el usuario deba diligenciar, en este caso solo "nombre" y "valor". Aquí es donde entra en juego omit:
type ProductoDto = Omit<Producto, 'id'>; // indicamos un nuevo tipo omitiendo el atributo id
...
crearProducto(data: PoductoDto){
const nuevoProducto = {
id: Math.random(),
...data
}
this.productos.push(nuevoProducto);
return nuevoProducto;
}
...
Partial
Permite generar un nuevo tipo a partir de otro pero estableciendo todas sus propiedades como opcionales. Siguiendo con el ejemplo anterior vamos a crear un nuevo método para actualizar productos pero dado que no necesitamos que todos los campos sean actualizados sino únicamente algunos usaremos el utility type Partial para este fin:Ahora creamos el método para actualizar los productos y como parámetro pasaremos un elemento de tipo "productoParaActualizar"Ahora si queremos por ejemplo actualizar solamente el valor de un producto podemos hacer lo siguiente:
...
type productoParaActualizar = Partial<Producto>;
...
actualizarProducto(id: number, data: productoParaActualizar){
const index = this.productos.findIndex(item=> item.id === id);
this.productos[index] = {
...this.productos[index],
...data
}
return this.productos[index];
}
const datosParaActualizar = {
valor: 6000
}
servicio.actualizarProducto(9, datosParaActualizar);
Pick
Al igual que el anterior establece todas las propiedades de un tipo como "opcionales" sin embargo explícitamente nos indica uno o mas campos que deben incluirse:
// todas las propiedades de Producto son opcionales excepto 'valor'
type PickProducto = Pick<Producto, 'valor'>;
Required
Exactamente lo opuesto de Partial, es decir, establece todas las propiedades de un tipo como obligatorias:
interface ProductoOpcional {
id?: number;
nombre?: string;
valor?: number;
}
// sin errores dado que las propiedades de "ProductoOpcional" son todas opcionales:
const ProductoOpcional01: ProductoOpcional = {valor: 3000};
// aquí obtendremos un error ya que con Required debemos pasar todas las propiedades
const ProductoOpcional02: Required<ProductoOpcional> = {valor: 3000};
Readonly
Construye un nuevo tipo cuyos atributos son de "solo lectura", es decir, no pueden ser reasignados:
interface ReadonlyProducto {
id: number;
nombre: string;
valor: number;
}
const ProductoReadOnly: Readonly<ReadonlyProducto> = {
id: 1,
nombre: 'barra de Chocolate',
valor: 5000
}
// obtendremos un error ya que al ser de tipo Readonly no podemos modificar un atributo de este elemento:
ProductoReadOnly.valor = 6000;
Record
Permite construir un tipo de objeto cuyas claves son el resultado de mapear las propiedades de un tipo en otro tipo.
interface Producto{
id: number;
nombre: string;
valor: number;
}
type TipoProductos = "yogurt" | "celular" | "audifonos";
const Productos: Record<TipoProductos, Producto> = {
yogurt: {id: 1, nombre: "Yogurt Multi Vitaminas", valor: 3000},
celular: {id: 2, nombre: "Xiamoi", valor: 4000},
audifonos: {id: 3, nombre: "TWS F9", valor: 5000}
}
Exclued
Construye un tipo a partir de la union de varios tipos excluyendo aquellos que se repiten:
type T0 = Exclude<"a" | "b" | "c", "a">;
// => type T0 = "b" | "c"
type T1 = Exclude<"a" | "b" | "c", "a" | "b">;
// => type T1 = "c"
Extract
Dado dos grupos de tipos, mantiene unicamente aquellos que pueden ser asignables en ambos grupos
type T0 = Extract<"a" | "b" | "c", "a" | "f">;
NoNullable
Construye un tipo excluyendo aquellos que son de tipo Null o Undefined
type T0 = NonNullable<string | number | undefined>;
// => type T0 = string | number
Parameters
Construye una tupla de tipos a partir de los tipos usados en los parámetros de una función
type T1 = Parameters<(s: string) => void>;
// => T1 = [s: string]
ReturnType
Construye un tipo consistente con el tipo de retorno de una función
type T0 = ReturnType<() => string>;
// => T0 = string