为什么一种类型的 T[keyof T] 会阻止接口中的协变

Why does a type of T[keyof T] prevent covariance in an interface

我正在尝试创建一个类型协变,以便 Type<Cat> 可以被视为 Type<Animal>(例如猫的列表就是动物的列表)。但出于某种原因,在 Type 接口的方法中使用类型 T[keyof T] 似乎可以防止这种情况发生。

type Animal = {
    legs: boolean;
}

type Dog = Animal & {
    golden: boolean;
}

//This exhibits covariance
interface Comparer<T> {
    compare(a: T, b: T): number;
}

//this is valid
declare let animalComparer: CovariantComparer<Animal>;
declare let dogComparer: CovariantComparer<Dog>;

animalComparer = dogComparer;
dogComparer = animalComparer;  

//This does not
interface NonCovariantComparer<T> {
    compare(a: T, b: T[keyof T]): number;
}

declare let animalComparer2: NonCovariantComparer<Animal>;
declare let dogComparer2: NonCovariantComparer<Dog>;

animalComparer2 = dogComparer2; //typeerror
dogComparer2 = animalComparer2; //typeerror

有什么办法可以做到吗?或者,如果不是,为什么不可能,是否有解决此问题的良好模式?谢谢!

注意:我假设 making the object a method will make it bivariant

Typescript playground example

在接口的 compare() 方法上添加泛型类型 U extends T 似乎可以解决错误:

type Animal = {
    legs: boolean;
}

type Dog = Animal & {
    golden: boolean;
}

interface CovariantComparer<T> {
    compare<U extends T>(a: T, b: U[keyof T]): number;
}

declare let animalComparer: CovariantComparer<Animal>;
declare let dogComparer: CovariantComparer<Dog>;

animalComparer = dogComparer;
dogComparer = animalComparer;

TypeScript Playground Link