¿Se pueden extender los tipos en TypeScript? Profundizando en rendimiento y optimización
¡Hola, amigo! Si alguna vez has escrito en TypeScript, seguramente te has enfrentado a la pregunta: "¿Se pueden extender los tipos de la misma manera que las interfaces?" Esta pregunta en Stack Overflow ha acumulado miles de visitas, y con razón. Parece simple: las interfaces se extienden con extends, y los tipos con intersecciones (&). Pero hay matices, y afectan directamente al rendimiento y la legibilidad del código.
Hoy analizaremos cómo extender tipos en TypeScript, en qué se diferencia de las interfaces, y cómo no meter la pata al optimizar. ¡Allá vamos!
Type vs Interface: la batalla eterna
Antes de hablar de extensión, recordemos la diferencia. Las interfaces son "contratos" que se pueden declarar varias veces (fusión declarativa), mientras que los tipos son alias (seudónimos) para cualquier forma. Ambos se pueden extender, pero de manera diferente.
¿Cómo extender interfaces?
Aquí todo es familiar:
interface Animal { name: string;}
interface Bear extends Animal { honey: boolean;}
const bear: Bear = { name: 'Winnie', honey: true };Simple, elegante, funciona. Pero, ¿qué pasa si queremos lo mismo para un tipo?
¿Cómo extender tipos?
Los tipos no soportan extends directamente. En su lugar, se usa el operador de intersección (&):
type Animal = { name: string;};
type Bear = Animal & { honey: boolean };
const bear: Bear = { name: 'Winnie', honey: true };Se ve similar, pero hay trampas. Analicémoslas con ejemplos.
Rendimiento: ¿qué es más rápido?
La pregunta del millón: ¿influye la elección entre interface extends o type & en la velocidad de compilación y ejecución? Spoiler: sí, pero no como crees.
Compilación: las interfaces ganan
TypeScript compila las interfaces más rápido que las intersecciones de tipos. ¿Por qué? Las interfaces son estructuras "planas" que el compilador puede almacenar en caché y procesar linealmente. Las intersecciones de tipos son construcciones complejas que pueden requerir expansión recursiva.
// Interfaz - rápidointerface A { a: string }interface B extends A { b: number }
// Tipo - más lentotype A = { a: string }type B = A & { b: number }En proyectos grandes con cientos de tipos, la diferencia puede ser notable. Pero si tienes 10-20 entidades, no lo notarás.
Ejecución: ninguna diferencia
TypeScript es una extensión de JavaScript. En tiempo de ejecución no hay ni interfaces ni tipos. Solo existen en la etapa de desarrollo. Por lo tanto, la velocidad de ejecución del programa no se ve afectada en absoluto.
¿Cuándo son mejores los tipos que las interfaces?
A pesar de la posible lentitud en la compilación, los tipos son indispensables en algunos escenarios:
- Union types — unión de tipos (por ejemplo,
string | number) - Conditional types — tipos condicionales (por ejemplo,
T extends string ? 'yes' : 'no') - Mapped types — transformación de propiedades (por ejemplo,
{ [K in keyof T]: boolean })
Las interfaces no pueden con esto. Pero si solo necesitas extender un objeto, las interfaces son las mejores.
Optimización: cómo no dispararte en el pie
Ahora lo más interesante. Cómo escribir tipos extensibles para no ralentizar la compilación ni confundir a tus colegas.
Regla 1: Usa interfaces para objetos, tipos para todo lo demás
Este es el estándar de oro. Si describes la forma de un objeto, usa interface. Si necesitas un union, intersection, o magia con genéricos, usa type.
// Bieninterface User { id: number; name: string;}
type Status = 'active' | 'inactive';type Admin = User & { role: 'admin' };<