Issue
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?)
Solution
As described in this TypeScript doc:
One of TypeScript’s core principles is that type checking focuses on the shape that values have. This is sometimes called “duck typing” or “structural typing”.
In "duck typing":
If it looks like a duck and swims like a duck, then in it's likely a duck.
In other words, TypeScript examines the shape (methods and properties) of a supplied object or type. If the supplied object contains all the properties and methods described by an interface, then the object can, in all likelihood, be treated as an object that is compatible with the described interface.
In your example, your interface and class look exactly the same, so TypeScript treats your object as compatible with the described interface.
If you examine the generated JavaScript, note that there is no mention of your interface at all - this is because TypeScript Interfaces are essentially developer-supplied type metadata that help TypeScript validate type compatibility.
Answered By - Rich Turner
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.