什么是协变和逆变
原来,在泛型参数上添加了in关键字作为泛型修饰符的话,那么那个泛型参数就只能用作方法的输入参数,或者只写属性的参数,不能作为方法返回值等,总之就是只能是“入”,不能出。out关键字反之。
上面标红的文字中,in表示逆变,out表示协变。用例子看下什么是协变和逆变。
逆变(contravariant)例子
class Animal {
private a: number = 1;
}
class Dog extends Animal{
private b: number = 1;
}
class Cat extends Animal{
private c: number = 1;
}interface Comparer<T> {
compare: (a: T, b: T) => number;
}declare let animalComparer: Comparer<Animal>;
declare let dogComparer: Comparer<Dog>;
animalComparer = dogComparer; // Error
dogComparer = animalComparer; // Ok
T泛型只作为输入参数,
此时Error的行将dogComparer赋给animalComparer,而dogComparer认为T是Dog类型,故而会调用Dog类型的专用方法,animalComparer的T限定为Animal类型,可能传Animal对象或Cat对象到函数参数,故而会报错。
OK行,则将animalComparer赋给dogComparer,animalComparer认为T是Animal类型,故而只会调用Animal类型的方法,dogComparer的T限定为Dog类型,一定匹配Animal类型,故而不会报错。
协变(covariant)例子
class Animal {
private a: number = 1;
}
class Dog extends Animal{
private b: number = 1;
}
class Cat extends Animal{
private c: number = 1;
}interface Comparer<T> {
compare: () => T;
}declare let animalComparer: Comparer<Animal>;
declare let dogComparer: Comparer<Dog>;
animalComparer = dogComparer; // Ok
dogComparer = animalComparer; // Error
T类型只作为返回值,
此时OK的行将dogComparer赋给animalComparer,dogComparer的compare函数返回Dog类型,肯定可以赋给animalComparer的compare函数的返回类型Animal。
Error行,则将animalComparer赋给dogComparer,animalComparer的compare函数的返回类型Animal是不能赋给dogComparer的compare函数返回Dog类型的,故报错。
–strictFunctionTypes限定主要关注的逆变赋值,关闭strictFunctionTypes开关后,逆变检测变成了双变检测(bivariantly),故而第一个例子里面的Error不会报错了。