I was having a play around with TypeScript and interfaces. I have the following piece of code
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);
Which compiles and runs without complaining. Can anyone please explain why my trigger function accepts b even though it expects to get a type Button and b is of type Control.
Even if Button were to explicitly implement Control, I'm asking for a Button not a Control. For all intended purposes, Button may contain additional members.
Is TypeScript inferring the implementation just because they are structurally the same? Are you allowed to pass an interface where an implementing class is expected? (shouldn't it be the other way around?)
Buttonhas a private member, only it (or classes that extend from it) will be considered compatible types. You might consider adding a 'dummy' private member if this is the desired behavior.triggeractually depends on aspects ofButtonother than the members it uses, after all.