Utility Types en TypeScript

2
184
Utility Types en TypeScript

Índice de contenidos

  1. Introducción
  2. Partial
  3. Pick
  4. Omit
  5. Record
  6. Exclude
  7. Extract
  8. Required
  9. Readonly
  10. NonNullable
  11. ReturnType
  12. Awaited
  13. Conclusión

Introducción

Como vimos en mi último articulo en el que hablaba sobre genéricos en Typescript, TypeScript no se limita al tipado estático simple, si no que nos proporciona una gran cantidad de herramientas que nos agilizan el desarrollo y hacen este más legible y simple.

En este artículo te voy a enseñar algunas de sus utilidades que te van a ayudar a mejorar tus desarrollos. Vamos a ello:

Partial

Partial nos permite tipar haciendo opcionales todas las propiedades del genérico que recibe como tipo. Podríamos decir que transforma un tipado estricto donde tienes que implementar todas las propiedades en un tipado menos agresivo donde te permite ‘elegir’ las propiedades que necesites.

interface TShirt {
	size: string,
	color: string,
	frontText: string,
	backText: string 
}

const customTShirt: Partial<TShirt> = {
	size: 'Small',
	color: 'blue'
	frontText: 'Change de future'
}

const otherCustomTShirt: Partial<TShirt> = {
	size: 'Large',
	color: 'green'
	backText: 'Change de future'
}

Pick

Pick nos permite tipar seleccionando las propiedades que queramos del genérico que le proporcionamos. Es decir, es como una versión simplificada.

type BasicTShirt = Pick<TShirt, 'size' | 'color'>

const basicTShirt: BasicTShirt = {
	size: 'Large',
	color: 'white'
}

Omit

Omit nos permite tipar omitiendo las propiedades que le indiquemos del genérico que le proporcionamos. Digamos que funciona igual que Pick pero esta vez las propiedades que le indicamos son las que no queremos que se incluyan en el nuevo tipo.

type TShitContent = Omit<TShirt, 'size' | 'color'>

const basicTShirt: BasicTShirt = {
	frontText: 'Change de future',
	backText: 'Change de future'
}

Record

Record nos permite tipar especificando el tipo de claves y el tipo de valor. Este caso se entiende mejor viendo un ejemplo.

interface TShirtModel {
	color: string,
	frontText: string,
	backText: string 
}

type Seasons = "summer" | "winter" | "spring" | "autumn"

const collections: Record<Seasons, TShirtModel> = {
    summer: { color: 'orange' , frontText: 'Summer', backText: 'Summer days'},
    winter: { color: 'blue' , frontText: 'Winter', backText: 'Winter days'},
    spring: { color: 'green' , frontText: 'Spring', backText: 'Spring days'},
    autumn: { color: 'brown' , frontText: 'Autumn', backText: 'Autumn days'},
}

Exclude

Exclude nos permite tipar excluyendo el tipo que le pasamos como segundo argumento al genérico que recibe como primer argumento.

interface TShirt {
	size: string,
	color: string,
	frontText: string,
	backText: string 
}

interface DeliveryPoint {
	address: string,
	city: string,
	postalCode: string
}

interface PaymentMethod {
	type: string,
	provider: string
}

type FullOrderInformation = TShirt & DeliveryPoint & PaymentMethod

const fullInfo: FullOrderInformation = {
	size: 'Medium',
	color: 'Black',
	frontText: 'Hello',
	backText: 'Bye',
	address: 'some direction',
	city: 'Madrid',
	postalCode: '32556',
	type: 'Credit Card',
	provider: 'Visa'
}

type DistrubutorInformation = Exclude<FullOrderInformation, PaymentMethod>

const distributorInfo: DistributorInformation = {
	size: 'Medium',
	color: 'Black',
	frontText: 'Hello',
	backText: 'Bye',
	address: 'some direction',
	city: 'Madrid',
	postalCode: '32556'
}

Extract

Extract nos permite tipar manteniendo las propiedades que se pueden asignar al tipo extraído.

Podríamos decir que extract busca las propiedades comunes entre los tipos proporcionados.

type TShirtMaterials = 'Cotton' | 'Polyester' | 'Linen'

type PantMaterials = 'Cotton' | 'Polyester' | 'Nylon'

type CommonMaterials = Extract<TShirtMaterials, PantMaterials> 

const commonMaterials: CommonMaterials = 'Cotton' | 'Polyester'

Required

Required establece todas las propiedades del tipo como requeridas.

interface TShirt {
	size: string,
	color: string,
	frontText?: string,
	backText?: string 
}

type FrontAndBackTextTShirt = Required<TShirt>

const basicTShirt: TShirt = {
	size: 'Large'
	color: 'yellow'
}

const otherTShirt: FrontAndBackTextTShirt = {
	size: 'Large'
	color: 'yellow'
}
// Esto daría error

Readonly

Readonly establece que todas las propiedades del genérico recibido sean únicamente de lectura, es decir, no podrán ser modificadas.

interface TShirt {
	size: string,
	color: string,
	frontText?: string,
	backText?: string 
}

let sampleTShirt: ReadOnly<TShirt> = {
  size: 'Medium',
	color: 'black'
}

sampleTShirt.color = 'red'
//Esto daría error ya que color no se puede sobrescribir

NonNullable

NonNullable nos permite tipar eliminando la posibilidad de tener propiedades null o undefined en el genérico que recibe.

type TShirtText = string | undefined

type SureTShirtText = NonNullable<TShirtText>

interface FrontAndBackTextTShirt {
	size: string,
	color: string,
	frontText: SureTShirtText,
	backText: SureTShirtText 
}

const someTShirt:FrontAndBackTextTShirt = {
	size: 'Small',
	color: 'grey',
	frontText: undefined, //Error ya que no puede ser ni null ni undefined
	backText: 'something' 
}

ReturnType

ReturnType nos permite obtener el tipo de los datos que devuelve una función.

type BasicTShirt = {
	size: string,
	color: string
}

function getSampleTShirt(): BasicTShirt { 
	...some action
} 

type SampleTShirt = ReturnType<typeof getSampleTShirt>
// { size: string, color: string }

Awaited

Awaited extrae el tipo que se resuelve de una promesa que es devuelta por una función.

async function getTShirtsQry(): Promise<TShirt[]> {
  ...some action
}

type TShirtList = Awaited<typeof getTShirtsQry>;

async function getTShirts(): Promise<void> {
  const listOfTShirts: TShirtList = await getTShirtsQry();
  // ... some action with this t-shirts
}

Conclusión

En este articulo hemos explorado las Utility Types mas interesantes que tiene TypeScript a día de hoy. Te animo a intentar utilizarlas, te aseguro una vez las tengas dominadas, verás que agilizan tu desarrollo y luego no podrás vivir sin algunas de ellas.

Gracias por tu atención 😊

2 COMENTARIOS

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad