【发布时间】:2018-07-27 12:54:57
【问题描述】:
看起来在 TypeScript 中拥有这样的代码绝对没问题(从编译器的角度来看):
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());
但与此同时,我预计会出现编译错误,因为Vehicle 和Task 没有任何共同点。
sane 用法可以通过显式接口定义来实现:
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());
...或一个共同的父对象:
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());
是的,对于 JavaScript 来说,拥有这样的行为绝对没问题,因为根本没有类和编译器(只有语法糖),而鸭子类型对于该语言来说是很自然的。但是 TypeScript 尝试引入静态检查、类、接口等。但是,在我看来,类实例的鸭式类型看起来相当混乱且容易出错。
【问题讨论】:
-
因为安德斯允许。我不知道他会不会路过并告诉你为什么。
-
@MuratK。不,如果您将返回类型更改为
number它仍然可以编译。 -
是的,我查过了。如果返回类型明显相同,它就可以工作
标签: javascript class typescript interface duck-typing