type constraints in generics behavior confusing

Topics: General
Sep 19, 2013 at 3:52 PM
as reported in bug #1694 I'm confused by the behavior of type constraints in the following example.
class test<A> {
    public testMethod (param: A): void {
    }
}

class base {
    constructor (public field: string) {}
}

var method = <T extends base> () : void => {
    var z = new test<T>();
    z.testMethod(new base("text")); // should not generate an error in text editor
}

var method2 = (): void => {
    var z = new test<number>();
    z.testMethod("text"); // should not compile
}

class B {
    public method3<T extends base> (): void {
        var z = new test<T>();
        z.testMethod(new base("text")); // should not generate an error in text editor
    }
    
    public method4 (): void {
        var z = new test<number>();
        z.testMethod("text"); // should not compile
    }
}
I think here "method" and "method3" should compile correctly, while "method2" and "method3" should not compile at all.

I'm not really convinced by danquirk"s asnwer on this subject (see bug discussion).
Coordinator
Sep 19, 2013 at 4:10 PM
Edited Sep 19, 2013 at 4:10 PM
I've taken your method example and renamed some things:
class List<A> {
    public add(param: A): void {
        /* ... */
    }
}

class Animal {
    constructor (public field: string) {}
}

var addAnimal = <T extends Animal> (someList: List<T>) : void => {
    someList.add(new Animal("rabbit!")); // Allowed?
}
Let's say we allow this. Consider this code -- it is obviously unsafe:
class Horse extends Animal {
    constructor(public height: number) {
        super('hay');
    }
}

var horses = new List<Horse>();
addAnimal(horses); // 'horses' now contains a non-horse (Animal)