CodeForge

Maquetación Web Dinámica / TypeScript en la maquetación

Datos tipados: interfaces y render seguro

Teoría22 min20 XP

En el módulo 14 renderizaste una lista desde un array de objetos. Pero nada te impedía escribir mal un campo (categoira), olvidar una propiedad o meter un valor inválido — y solo lo descubrías cuando la tarjeta salía rota. Con TypeScript defines la FORMA exacta de tus datos con una interfaz, y a partir de ahí todo —crear los datos, renderizarlos, cambiarlos— queda verificado. Es el superpoder más útil de TS para el maquetador.

La interfaz: el molde de tus datos

tipos-datos.ts
// la FORMA de una noticia: qué campos y de qué tipo
interface Noticia {
titulo: string;
categoria: "Ambiente" | "Ciudad" | "Cultura";   // tipo UNIÓN: solo estos 3 valores
resumen: string;
destacada?: boolean;   // el '?' la hace OPCIONAL
}

// un array tipado: cada objeto DEBE cumplir la forma Noticia
const noticias: Noticia[] = [
{ titulo: "El páramo que fabrica agua", categoria: "Ambiente", resumen: "..." },
{ titulo: "Nueva ciclorruta", categoria: "Deportes", resumen: "..." },
// ❌ Error: "Deportes" no es asignable a "Ambiente" | "Ciudad" | "Cultura"
];

Dos cosas potentes ya visibles: el tipo unión ("Ambiente" | "Ciudad" | "Cultura") restringe categoria a valores válidos —escribe "Deportes" o "Ambiete" y TS lo rechaza, además de autocompletar los correctos—; y el ? marca campos opcionales. Si olvidas resumen, TS te avisa que falta.

Render tipado: entra Noticia[], sale HTML

render.ts
// la función declara qué recibe (Noticia[]) y qué devuelve (string)
function render(items: Noticia[]): string {
return items
  .map((n) => "<article class='noticia'><span class='cat'>" + n.categoria +
    "</span><h3>" + n.titulo + "</h3></article>")
  .join("");
}
// dentro del map, 'n' es una Noticia: n.titulo autocompleta, n.titluo da error

Al tipar el parámetro como Noticia[], dentro del map cada n es una Noticia: el editor te autocompleta n.titulo, n.categoria, y si escribes n.titluo (typo) o n.precio (campo inexistente), rojo al instante. La función también declara que DEVUELVE string: si por error retornaras otra cosa, TS lo detecta.

El superpoder: cambia la forma, TS encuentra todo

Corriendo (el render, compilado)

Defines interface Producto con un campo precio: number. Más adelante decides que precio debe ser un objeto { valor: number, moneda: string }. ¿Qué te da TypeScript al hacer ese cambio?

Mini-reto

Convierte las noticias de "El Observador" en datos tipados: define interface Noticia con titulo, categoria (unión de tus secciones), resumen y un destacada? opcional, crea el array Noticia[] y una función render(items: Noticia[]): string. Luego prueba el superpoder: renombra titulo a titular en la interfaz y observa cuántos sitios se encienden en rojo pidiéndote el cambio. Ese mapa es lo que hace grande a TypeScript.

Qué sigue

Tienes todo el arsenal: elementos, eventos, patrones y datos, tipados. El reto del módulo lo reúne: migrar el proyecto completo del módulo 14 —la página viva con reveals, navbar y modal— a TypeScript estricto, sin un solo error del compilador. Tu graduación como maquetador con red de seguridad.