Los tipos mapeados en TypeScript son una poderosa característica que permite transformar tipos existentes en nuevos tipos. Esto es especialmente útil cuando necesitas crear tipos derivados de otros tipos de manera dinámica y reutilizable.

Conceptos Clave

  1. Tipos Mapeados Básicos: Permiten crear un nuevo tipo basado en las propiedades de un tipo existente.
  2. Modificadores de Propiedades: Puedes agregar, eliminar o modificar propiedades en los tipos mapeados.
  3. Tipos Mapeados Condicionales: Permiten aplicar condiciones a las propiedades de los tipos mapeados.

Tipos Mapeados Básicos

Un tipo mapeado básico toma un tipo existente y crea un nuevo tipo con las mismas propiedades, pero con posibles modificaciones. La sintaxis básica es:

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

Ejemplo Práctico

Supongamos que tenemos una interfaz Person:

interface Person {
  name: string;
  age: number;
  address: string;
}

Podemos crear un tipo mapeado que tenga las mismas propiedades que Person:

type PersonMapped = {
  [P in keyof Person]: Person[P];
};

// Uso del tipo mapeado
const person: PersonMapped = {
  name: "John",
  age: 30,
  address: "123 Main St"
};

Modificadores de Propiedades

Haciendo Propiedades Opcionales

Puedes hacer que todas las propiedades de un tipo sean opcionales usando el modificador ?:

type Partial<T> = {
  [P in keyof T]?: T[P];
};

type PartialPerson = Partial<Person>;

// Uso del tipo mapeado con propiedades opcionales
const partialPerson: PartialPerson = {
  name: "John"
  // 'age' y 'address' son opcionales
};

Haciendo Propiedades de Solo Lectura

Puedes hacer que todas las propiedades de un tipo sean de solo lectura usando el modificador readonly:

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

type ReadonlyPerson = Readonly<Person>;

// Uso del tipo mapeado con propiedades de solo lectura
const readonlyPerson: ReadonlyPerson = {
  name: "John",
  age: 30,
  address: "123 Main St"
};

// readonlyPerson.name = "Jane"; // Error: no se puede asignar a 'name' porque es una propiedad de solo lectura.

Tipos Mapeados Condicionales

Los tipos mapeados condicionales permiten aplicar condiciones a las propiedades de los tipos mapeados. Por ejemplo, puedes transformar las propiedades de un tipo basado en una condición:

type Nullable<T> = {
  [P in keyof T]: T[P] | null;
};

type NullablePerson = Nullable<Person>;

// Uso del tipo mapeado con propiedades que pueden ser nulas
const nullablePerson: NullablePerson = {
  name: "John",
  age: null,
  address: "123 Main St"
};

Ejercicio Práctico

Ejercicio 1: Creando un Tipo Mapeado

Crea un tipo mapeado Mutable<T> que haga que todas las propiedades de un tipo sean mutables (no de solo lectura).

type Mutable<T> = {
  // Tu código aquí
};

interface Car {
  readonly make: string;
  readonly model: string;
  readonly year: number;
}

type MutableCar = Mutable<Car>;

const car: MutableCar = {
  make: "Toyota",
  model: "Corolla",
  year: 2020
};

car.make = "Honda"; // Esto debería ser permitido

Solución

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

interface Car {
  readonly make: string;
  readonly model: string;
  readonly year: number;
}

type MutableCar = Mutable<Car>;

const car: MutableCar = {
  make: "Toyota",
  model: "Corolla",
  year: 2020
};

car.make = "Honda"; // Esto es permitido

Conclusión

Los tipos mapeados en TypeScript son una herramienta poderosa para transformar y manipular tipos de manera dinámica. Permiten crear tipos derivados de otros tipos, hacer propiedades opcionales o de solo lectura, y aplicar condiciones a las propiedades. Con estos conocimientos, puedes escribir código más flexible y reutilizable.

En el próximo tema, exploraremos los Tipos Condicionales, que nos permitirán aplicar lógica condicional a los tipos en TypeScript.

© Copyright 2024. Todos los derechos reservados