为什么一种类型的 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
有什么办法可以做到吗?或者,如果不是,为什么不可能,是否有解决此问题的良好模式?谢谢!
在接口的 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;
我正在尝试创建一个类型协变,以便 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
有什么办法可以做到吗?或者,如果不是,为什么不可能,是否有解决此问题的良好模式?谢谢!
在接口的 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;