Typescript的協(xié)變和逆變和C# Scala中的類似淳地,但是Typescript的會自動算出來接口屬于協(xié)變還是逆變,C# Scala中需要顯示聲明in out標(biāo)記接口澎羞。 在typescript需要在tsconfig中使用strictFunctionTypes參數(shù)開啟逆變檢查藕筋,否則就是雙變(協(xié)變或者逆變)绵跷。
逆變接口
接口中泛型只作為函數(shù)類型參數(shù)
interface Animal {
Eat(): void
}
interface Dog extends Animal{
Bark():void
}
interface Cat extends Animal{
Meow():void
}
interface Comparer<T> {
compareA: (a: T, b: T) => number;
}
逆變接口的賦值類型檢查
declare let animalComparer: Comparer<Animal>;
declare let dogComparer: Comparer<Dog>;
animalComparer = dogComparer;
/*
錯誤锐极, 因為調(diào)用 animalComparer(Dog)的時候笙僚,
dogComparer會接受到一個Animal類型的參數(shù)芳肌,這是有風(fēng)險的
*/
dogComparer = animalComparer; // 正確
例外情況
interface Comparer<T> {
compareA(a: T, b: T): number;
}
declare let animalComparer: Comparer<Animal>;
declare let dogComparer: Comparer<Dog>;
animalComparer = dogComparer; //正確
dogComparer = animalComparer; // 正確
/*
因為
compareA(a: T, b: T): number;
和
compareA: (a: T, b: T) => number;
不太一樣灵再,前者認(rèn)為是雙變, 后者認(rèn)為是逆變亿笤。這樣做的相當(dāng)于把方法類型的聲明排除在外,目的在于為了確保帶泛型的類和接口(如 Array)總體上仍然保持協(xié)變翎迁。
*/
協(xié)變接口
接口中泛型只作為函數(shù)類型返回值
interface Animal {
Eat(): void
}
interface Dog extends Animal{
Bark():void
}
interface Cat extends Animal{
Meow():void
}
interface Comparer<T> {
compareB: () => T;
}
協(xié)變接口的賦值類型檢查
declare let animalComparer: Comparer<Animal>;
declare let dogComparer: Comparer<Dog>;
animalComparer = dogComparer;
// 正確
dogComparer = animalComparer;
/*
錯誤, 因為調(diào)用 dogComparer(Dog)的時候净薛,
animalComparer會返回一個Animal類型的值汪榔,這是有風(fēng)險的
*/