Por que a digitação com patos é permitida para classes no TypeScript
Parece que no TypeScript é absolutamente bom (da perspectiva do compilador) ter esse 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());
Mas, ao mesmo tempo, eu esperaria umaErro de compilação, PorqueVehicle
eTask
não tem nada em comum.
Esão os usos podem ser implementados via definição explícita da interface:
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());
... ou um objeto pai comum:
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());
E sim, para JavaScript é absolutamente bom ter esse comportamento, porque não há classes e nenhum compilador (apenas açúcar sintático) e a digitação com patos é natural para o idioma. Porém, o TypeScript tenta introduzir verificações estáticas, classes, interfaces, etc. No entanto, a digitação de pato para instâncias de classe parece bastante confusa e propensa a erros, na minha opinião.