3

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!

2
  • Your fight explicitly requires a Civilian instance fight: (villian: Civilian) => void; If you had used ComicBookCharacter as the parameter type, it wouldn't compile successfully. If that's not the issue you mean, could you please provide a bit more detail about the problem? Commented Mar 8, 2014 at 17:10
  • 4
    well they did get married. Fighting was inevitable Commented Mar 8, 2014 at 23:15

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

1 Comment

Not a bug; this is intentional. Function argument types are bivariant.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.