Consider the interface CommicBookCharacter
interface CommicBookCharacter {
name: string;
fight : (nemisis: CommicBookCharacter) => void;
}
Which may be implemented by both heros and villian. Besides of these characters, there are also civilians
class Civilian{
constructor(public name: string) {}
}
and here is how a hero could be implemented
class SuperHero implements CommicBookCharacter {
fight: (villian: Civilian) => void;
constructor(public name: string) {
this.fight = (hero)=> {
alert(this.name + ' is struggling back');
};
}
}
Lets create some characters as well
var spiderMan= new SuperHero('Spider Man');
var mj = new Civilian('Mary Jane');
Here is my problem. The civilian class does not implement the ComicBookCharacter interface, but the SuperHero can still implement the fight method with the Civilian argument.
This results in some bad problems:
spiderMan.fight(mj);
As a side note: if I would change the type of villian in the SuperHeru class to, say string, it would give me an compilation error. In my opinion, this is a buggy behavior. SpiderMan should not be able to fight Mary Jane!
You are explicitly accepting a Civilian as an argument :
interface ComicBookCharacter {
name: string;
fight: (nemisis: ComicBookCharacter) => void;
}
class Civilian{}
class SuperHero implements ComicBookCharacter {
name:string;
// You explicitly accept Civilian
fight = (villian: Civilian) => {};
}
This interface implementation is allowed since function argument types are bivariant, (as pointed out by Ryan)
PS: Related https://typescript.codeplex.com/workitem/2282 In particular : https://typescript.codeplex.com/workitem/2282#CommentContainer6
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With