CodeForge

TypeScript de Cero a Experto / Narrowing

Reto: un reducer tipado con exhaustividad

Reto35 min60 XP

El reto que junta el módulo entero y te deja construyendo justo lo que usarás en React: un reducer para "Mi Bolsillo" donde las acciones son una discriminated union, cada una se maneja con narrowing preciso, y un assertNever garantiza que no falte ningún caso. Es el patrón de manejo de estado más importante del frontend, tipado de punta a punta.

Reto

El reducer de Mi Bolsillo

Media30 min60 XP(×2 sin mirar la solución)

Qué debes construir

Un reducer tipado que aplica acciones sobre una lista de gastos. Al ejecutarse debe imprimir EXACTAMENTE:

terminal

Tras agregar: 3 gastos, total 31800

Tras borrar Bus: 2 gastos, total 29000

Tras renombrar: Cafe con leche

Tras limpiar: 0 gastos, total 0

Requisitos:

  1. type Gasto: { id: number; nombre: string; valor: number }.
  2. type Accion — una discriminated union con campo tipo:
    • { tipo: "agregar"; id: number; nombre: string; valor: number }
    • { tipo: "borrar"; id: number }
    • { tipo: "renombrar"; id: number; nombre: string }
    • { tipo: "limpiar" }
  3. assertNever(x: never): never que lance con el caso no manejado.
  4. reducer(estado: Gasto[], accion: Accion): Gasto[]: un switch sobre accion.tipo que maneje cada caso de forma INMUTABLE (devuelve un array nuevo, nunca muta el original), con assertNever en el default.
  5. El guion: agregar tres gastos, borrar el "Bus", renombrar el primero a "Cafe con leche", y limpiar —imprimiendo el estado en cada punto.

Reglas

  • El reducer es PURO e inmutable (módulo 12 de JS): nada de push/mutación; [...], map, filter.
  • Cada case usa solo los campos de SU variante (narrowing por el discriminante).
  • El default llama a assertNever (no lo borres: es el guardián).
  • Salida exacta.

30:00

Cuando estés listo, arranca el reloj.

Qué sigue

Módulo 4 cerrado: TypeScript razona sobre tus datos como tú, y modelas casos con una precisión que hace imposibles los errores. El módulo 5 desbloquea la magia mayor del sistema de tipos: los GENÉRICOS —código que funciona con CUALQUIER tipo sin renunciar a la seguridad—. La pieza que hace reutilizables tus funciones y estructuras, de identity<T> a las colecciones tipadas.