I'm attempting to enable type covariance so that Type<Cat>
can be treated as a Type<Animal>
, for instance, treating a list of Cats as a list of Animals. However, using the type T[keyof T]
in a method within the Type interface seems to hinder this behavior.
type Animal = {
legs: boolean;
}
type Dog = Animal & {
golden: boolean;
}
// Demonstrates 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 work
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
Is there a way to make this setup function as desired? If not, why is it impossible and are there effective patterns to overcome this hurdle? Thank you!
Note: I am operating under the assumption that making the object a method will make it bivariant