Volver a TypeScript Básico
TypeScript
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
abstractcuando quieras compartir implementación y reforzar una interfaz. Usainterfacecuando solo quieras definir el contrato.