Stack Overflow Asked by bdwain on December 20, 2021
I am trying to make a type covariant so that Type<Cat>
can be treated as a Type<Animal>
for example (like a list of Cats is a list of Animals). But for some reason, using the type T[keyof T]
in a method in the Type interface seems to prevent that.
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
Is there a way to make that work? Or if not, why is it impossible and is there a good pattern to get around this issue? Thanks!
Note: I’m working off of the assumption that making the object a method will make it bivariant
Adding a generic type U extends T
on the compare()
method of the interface seems to resolve the errors:
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;
Answered by Patrick Roberts on December 20, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP