Skip to content

Lección 84 — Extensión de Interfaces

Las interfaces en TypeScript pueden extenderse mediante extends, heredando propiedades de una o más interfaces padres. También pueden reabrirse para añadir nuevas propiedades en diferentes partes del código.

interface Persona {
nombre: string;
edad: number;
}
interface Empleado extends Persona {
salario: number;
puesto: string;
}
const empleado: Empleado = {
nombre: 'Ana', // de Persona
edad: 30, // de Persona
salario: 50000, // propio
puesto: 'Ingeniera' // propio
};

Puedes extender varias interfaces a la vez:

interface Identificable {
id: number;
}
interface Nombrable {
nombre: string;
}
interface Contactable {
email: string;
}
interface Usuario extends Identificable, Nombrable, Contactable {
activo: boolean;
}
const usuario: Usuario = {
id: 1,
nombre: 'Ana',
email: 'ana@mail.com',
activo: true
};

A diferencia de los types, las interfaces se pueden reabrir — declarar la misma interfaz varias veces y TS fusiona las propiedades:

interface Producto {
id: number;
nombre: string;
}
// En otro archivo o más abajo
interface Producto {
precio: number;
disponible: boolean;
}
// Producto ahora tiene: id, nombre, precio, disponible
const camiseta: Producto = {
id: 1,
nombre: 'Camiseta',
precio: 19.99,
disponible: true
};

Una interface puede extender un type:

type CoordenadasBase = {
x: number;
y: number;
};
interface Coordenadas3D extends CoordenadasBase {
z: number;
}
const punto: Coordenadas3D = { x: 10, y: 20, z: 30 };

Una interface también puede extender una clase (hereda los miembros de la clase, incluyendo privados y protegidos):

class Controlador {
private estado: boolean = false;
}
interface ControladorAvanzado extends Controlador {
encender(): void;
apagar(): void;
}
// Jerarquía de interfaces
interface Serializable {
toJSON(): object;
}
interface Versionable {
version: number;
}
interface Documento extends Serializable, Versionable {
titulo: string;
contenido: string;
}
class Articulo implements Documento {
titulo: string;
contenido: string;
version: number = 1;
constructor(titulo: string, contenido: string) {
this.titulo = titulo;
this.contenido = contenido;
}
toJSON(): object {
return {
titulo: this.titulo,
contenido: this.contenido,
version: this.version
};
}
}

Crea tres interfaces base: Describible (con método describir(): string), Identificable (con id: number), y Fechable (con creadoEn: Date). Luego crea una interfaz Tarea que extienda las tres y añada titulo: string, completada: boolean. Implementa un objeto Tarea y llama a describir().

Si extiendes dos interfaces que tienen la misma propiedad con tipos incompatibles, obtendrás un error. Si tienen el mismo tipo, se fusionan sin problema.

La reapertura de interfaces es ideal para extender tipos globales. Por ejemplo, puedes añadir métodos a Window o Array en tus propios archivos de declaración.