¿Por qué se permite escribir pato para las clases en TypeScript?
Parece que en TypeScript está absolutamente bien (desde la perspectiva del compilador) tener ese código:
class Vehicle {
public run(): void { console.log('Vehicle.run'); }
}
class Task {
public run(): void { console.log('Task.run'); }
}
function runTask(t: Task) {
t.run();
}
runTask(new Task());
runTask(new Vehicle());
Pero al mismo tiempo esperaría unerror de compilación, porqueVehicle
yTask
No tengo nada en común.
Ycuerdo los usos se pueden implementar a través de la definición explícita de la interfaz:
interface Runnable {
run(): void;
}
class Vehicle implements Runnable {
public run(): void { console.log('Vehicle.run'); }
}
class Task implements Runnable {
public run(): void { console.log('Task.run'); }
}
function runRunnable(r: Runnable) {
r.run();
}
runRunnable(new Task());
runRunnable(new Vehicle());
... o un objeto principal común:
class Entity {
abstract run(): void;
}
class Vehicle extends Entity {
public run(): void { console.log('Vehicle.run'); }
}
class Task extends Entity {
public run(): void { console.log('Task.run'); }
}
function runEntity(e: Entity) {
e.run();
}
runEntity(new Task());
runEntity(new Vehicle());
Y sí, para JavaScript está absolutamente bien tener ese comportamiento, porque no hay clases ni compilador (solo azúcar sintáctico) y la tipificación de pato es natural para el lenguaje. Pero TypeScript intenta introducir comprobaciones estáticas, clases, interfaces, etc. Sin embargo, el tipeo de pato para instancias de clase parece bastante confuso y propenso a errores, en mi opinión.