我正在尝试使用 TypeScript 和界面。我有以下一段代码
interface Control {
name: string;
onSelect():string;
}
class Button {
name:string="button";
onSelect = function() {
return "hello";
}
}
var a:Button = new Button();
var b:Control = {"name": "arbitrary", "onSelect": () => { return "ahoy!"; }};
var trigger = function(c:Button) {
console.log(c.name, "says", c.onSelect());
}
trigger(a);
trigger(b);
编译和运行没有提示。任何人都可以解释为什么我的 trigger
函数接受 b
即使它期望得到类型 Button
而 b
是类型为 Control
。
即使 Button
明确实现了 Control
,我要求的是 Button
而不是 Control
.出于所有预期目的,Button
可能包含其他成员。
TypeScript 是否仅仅因为它们在结构上相同而推断实现?您是否允许在需要实现类的地方传递接口(interface)? (不应该反过来吗?)
最佳答案
如 TypeScript documentation on interfaces 中所述:
One of TypeScript's core principles is that type-checking focuses on the 'shape' that values have. This is sometimes called "duck typing"
If it looks like a duck and swims like a duck, then in it's likely a duck.
换句话说,TypeScript 检查提供的对象或类型的形状(方法和属性)。如果提供的对象包含接口(interface)描述的所有属性和方法,那么该对象很可能被视为与所描述的接口(interface)兼容的对象。
在您的示例中,您的接口(interface)和类看起来完全相同,因此 TypeScript 将您的对象视为与所描述的接口(interface)兼容。
如果你examine the generated JavaScript ,请注意根本没有提及您的接口(interface) - 这是因为 TypeScript 接口(interface)本质上是开发人员提供的类型元数据,可帮助 TypeScript 验证类型兼容性。
关于TypeScript 接口(interface)和实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27429988/