Volver a TypeScript Básico

Clases en TypeScript

TypeScript mejora las clases de JavaScript con modificadores de acceso, clases abstractas y verificación de tipos completa.

Modificadores de Acceso

class CuentaBancaria { // public — accesible en cualquier lugar (por defecto) public titular: string; // private — solo dentro de la clase private saldo: number; // protected — dentro de la clase y subclases protected tipoCuenta: string; // readonly — solo puede establecerse en el constructor readonly id: string; constructor(titular: string, saldoInicial: number) { this.titular = titular; this.saldo = saldoInicial; this.tipoCuenta = "corriente"; this.id = crypto.randomUUID(); } depositar(monto: number): void { if (monto <= 0) throw new RangeError("El monto debe ser positivo"); this.saldo += monto; } retirar(monto: number): void { if (monto > this.saldo) throw new Error("Fondos insuficientes"); this.saldo -= monto; } obtenerSaldo(): number { return this.saldo; } } const cuenta = new CuentaBancaria("Alice", 1000); cuenta.depositar(500); // cuenta.saldo; // Error: 'saldo' es privado

Forma Abreviada del Constructor

// Forma larga class Usuario { public nombre: string; private correo: string; readonly id: number; constructor(nombre: string, correo: string, id: number) { this.nombre = nombre; this.correo = correo; this.id = id; } } // Forma abreviada — parámetros de propiedad class Usuario { constructor( public nombre: string, private correo: string, readonly id: number, ) {} }

Clases Abstractas

abstract class Figura { abstract area(): number; abstract perimetro(): number; // Método concreto compartido por todas las figuras describir(): string { return `Área: ${this.area().toFixed(2)}, Perímetro: ${this.perimetro().toFixed(2)}`; } } class Circulo extends Figura { constructor(private radio: number) { super(); } area(): number { return Math.PI * this.radio ** 2; } perimetro(): number { return 2 * Math.PI * this.radio; } } class Rectangulo extends Figura { constructor(private ancho: number, private alto: number) { super(); } area(): number { return this.ancho * this.alto; } perimetro(): number { return 2 * (this.ancho + this.alto); } } const figuras: Figura[] = [new Circulo(5), new Rectangulo(4, 6)]; figuras.forEach(f => console.log(f.describir()));

Implementar Interfaces

interface Serializable { serializar(): string; deserializar(datos: string): this; } interface Cloneable<T> { clonar(): T; } class Configuracion implements Serializable, Cloneable<Configuracion> { constructor(private readonly datos: Record<string, unknown>) {} serializar(): string { return JSON.stringify(this.datos); } deserializar(json: string): this { return new Configuracion(JSON.parse(json)) as this; } clonar(): Configuracion { return new Configuracion({ ...this.datos }); } }

Consejo de diseño: Usa clases abstract cuando quieras compartir implementación y reforzar una interfaz. Usa interface cuando solo quieras definir el contrato.