CAP 05 · LEC 03·TypeScript

Unions e intersecciones: componer tipos

Los tipos union (|) e intersección (&) son las operaciones fundamentales para componer tipos en TypeScript. Con ellos puedes modelar relaciones complejas sin duplicar código.

● INTERMEDIO10 min lectura4 ejerciciospor Fernando Herrera · actualizado mayo de 2026
¿Encontraste un error o algo que mejorar?Editá esta lección en GitHub →

Tipos union (|)

Un tipo union significa "puede ser uno u otro". El valor puede ser de cualquiera de los tipos listados.

// Un parámetro que acepta número o string function mostrarId(id: number | string): void { console.log("ID:", id); } mostrarId(42); // "ID: 42" mostrarId("abc-99"); // "ID: abc-99" // Union de literales — solo esos valores exactos type Direccion = "norte" | "sur" | "este" | "oeste"; type HttpMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH"; type EstadoSemaforo = "rojo" | "amarillo" | "verde"; let dir: Direccion = "norte"; // dir = "arriba"; // ❌ Error // Union con null/undefined (nullable) type MaybeString = string | null; type OptionalNumber = number | undefined; function buscar(id: number): Usuario | null { return encontrarEnBD(id) ?? null; }

Narrowing en unions

Cuando tienes una union, TypeScript requiere que estreches (narrow) el tipo antes de usar métodos específicos de uno de los tipos:

function formatear(valor: number | string): string { // ❌ No puedes asumir que es string o number sin verificar // return valor.toUpperCase(); // Error: number no tiene toUpperCase if (typeof valor === "string") { return valor.toUpperCase(); // ✅ Aquí TypeScript sabe que es string } return valor.toFixed(2); // ✅ Aquí sabe que es number } console.log(formatear("hola")); // "HOLA" console.log(formatear(3.14159)); // "3.14" // Narrowing con instanceof function procesar(val: Date | string): string { if (val instanceof Date) { return val.toISOString(); // ✅ es Date } return new Date(val).toISOString(); // ✅ es string }
SalidaHOLA 3.14

Unions discriminadas

El patrón más potente: agrega una propiedad literal (kind, type, status) para distinguir variantes:

type Círculo = { kind: "circle"; radio: number; }; type Rectángulo = { kind: "rect"; ancho: number; alto: number; }; type Triángulo = { kind: "triangle"; base: number; altura: number; }; type Forma = Círculo | Rectángulo | Triángulo; function área(forma: Forma): number { switch (forma.kind) { case "circle": return Math.PI * forma.radio ** 2; case "rect": return forma.ancho * forma.alto; case "triangle": return (forma.base * forma.altura) / 2; default: { const _: never = forma; // exhaustive check throw new Error("Forma desconocida"); } } } console.log(área({ kind: "circle", radio: 5 }).toFixed(2)); // "78.54" console.log(área({ kind: "rect", ancho: 4, alto: 6 })); // 24 console.log(área({ kind: "triangle", base: 3, altura: 8 })); // 12
Salida78.54 24 12

Tipos intersección (&)

Un tipo intersección significa "debe ser ambos a la vez". Combina todas las propiedades:

interface Persona { nombre: string; edad: number; } interface Empleado { empresa: string; cargo: string; } type EmpleadoPersona = Persona & Empleado; const trabajador: EmpleadoPersona = { nombre: "Ana", edad: 30, empresa: "TechCorp", cargo: "Desarrolladora", }; // Útil para mixins / composición type ConTimestamp = { creado: Date; actualizado: Date; }; type UsuarioCompleto = Persona & EmpleadoPersona & ConTimestamp;
Union (|)Intersección (&)
Significado"uno u otro""ambos a la vez"
Propiedades disponiblesSolo las comunes a todos los tiposTodas las propiedades de todos los tipos
Cuándo usarValor puede ser de tipos distintosCombinar múltiples tipos en uno
Ejemplostring | numberPersona & Empleado

Practica