En este tema, exploraremos algunas de las características más avanzadas de TypeScript para la manipulación de tipos. Estas herramientas permiten crear tipos más flexibles y reutilizables, lo que puede ser extremadamente útil en proyectos grandes y complejos.

Contenido

  1. Tipos Condicionales
  2. Tipos Mapeados
  3. Inferencia de Tipos
  4. Utilidades de Tipos Integradas
  5. Ejercicios Prácticos

  1. Tipos Condicionales

Los tipos condicionales permiten definir tipos basados en una condición. La sintaxis básica es:

T extends U ? X : Y

Esto se lee como: "Si T extiende U, entonces el tipo es X; de lo contrario, es Y".

Ejemplo

type IsString<T> = T extends string ? "Yes" : "No";

type A = IsString<string>;  // "Yes"
type B = IsString<number>;  // "No"

En este ejemplo, IsString es un tipo condicional que verifica si T es un string.

  1. Tipos Mapeados

Los tipos mapeados permiten crear nuevos tipos transformando las propiedades de un tipo existente.

Ejemplo

type Readonly<T> = {
  readonly [P in keyof T]: T[P];
};

interface User {
  id: number;
  name: string;
}

type ReadonlyUser = Readonly<User>;

// ReadonlyUser es equivalente a:
// {
//   readonly id: number;
//   readonly name: string;
// }

En este ejemplo, Readonly es un tipo mapeado que convierte todas las propiedades de T en propiedades de solo lectura.

  1. Inferencia de Tipos

La inferencia de tipos permite a TypeScript deducir tipos automáticamente en ciertas situaciones, lo que puede simplificar la definición de tipos complejos.

Ejemplo

type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;

function getUser() {
  return { id: 1, name: "John" };
}

type User = ReturnType<typeof getUser>;  // { id: number; name: string; }

En este ejemplo, ReturnType es un tipo condicional que infiere el tipo de retorno de una función.

  1. Utilidades de Tipos Integradas

TypeScript proporciona varias utilidades de tipos integradas que facilitan la manipulación de tipos.

Ejemplo

Utilidad Descripción
Partial<T> Convierte todas las propiedades de T en opcionales.
Required<T> Convierte todas las propiedades de T en requeridas.
Readonly<T> Convierte todas las propiedades de T en de solo lectura.
Pick<T, K> Crea un tipo con un subconjunto de las propiedades de T.
Omit<T, K> Crea un tipo omitiendo un subconjunto de las propiedades de T.
interface User {
  id: number;
  name: string;
  email?: string;
}

type PartialUser = Partial<User>;  // { id?: number; name?: string; email?: string; }
type RequiredUser = Required<User>;  // { id: number; name: string; email: string; }
type ReadonlyUser = Readonly<User>;  // { readonly id: number; readonly name: string; readonly email?: string; }
type PickUser = Pick<User, "id" | "name">;  // { id: number; name: string; }
type OmitUser = Omit<User, "email">;  // { id: number; name: string; }

  1. Ejercicios Prácticos

Ejercicio 1: Crear un Tipo Condicional

Crea un tipo condicional IsArray<T> que verifique si T es un array.

type IsArray<T> = T extends any[] ? "Yes" : "No";

type Test1 = IsArray<number[]>;  // "Yes"
type Test2 = IsArray<string>;  // "No"

Ejercicio 2: Crear un Tipo Mapeado

Crea un tipo mapeado Mutable<T> que elimine la propiedad de solo lectura de todas las propiedades de T.

type Mutable<T> = {
  -readonly [P in keyof T]: T[P];
};

interface ReadonlyUser {
  readonly id: number;
  readonly name: string;
}

type MutableUser = Mutable<ReadonlyUser>;  // { id: number; name: string; }

Ejercicio 3: Utilizar Inferencia de Tipos

Crea un tipo Parameters<T> que extraiga los tipos de los parámetros de una función.

type Parameters<T> = T extends (...args: infer P) => any ? P : never;

function updateUser(id: number, name: string) {}

type Params = Parameters<typeof updateUser>;  // [number, string]

Conclusión

En esta sección, hemos explorado algunas de las características más avanzadas de TypeScript para la manipulación de tipos, incluyendo tipos condicionales, tipos mapeados, inferencia de tipos y utilidades de tipos integradas. Estas herramientas son esenciales para escribir código TypeScript robusto y flexible, especialmente en proyectos grandes y complejos. Asegúrate de practicar estos conceptos con los ejercicios proporcionados para consolidar tu comprensión.

© Copyright 2024. Todos los derechos reservados