I'm currently diving into the examples provided in the Typescript advanced types handbook to broaden my understanding.
According to the explanation:
The next example showcases how having multiple potential values for the same type variable in co-variant positions leads to an inferred union type:
type Foo<T> = T extends { a: infer U, b: infer U } ? U : never;
type T10 = Foo<{ a: string, b: string }>; // string
type T11 = Foo<{ a: string, b: number }>; // string | number
Similarly, when there are multiple possible values for the same type variable in contra-variant positions, it results in an inferred intersection type:
type Bar<T> = T extends { a: (x: infer U) => void, b: (x: infer U) => void } ? U : never;
type T20 = Bar<{ a: (x: string) => void, b: (x: string) => void }>; // string
type T21 = Bar<{ a: (x: string) => void, b: (x: number) => void }>; // string & number
This raises the question: why are the object properties in the first example referred to as "co-variant positions" while the function arguments in the second example are called "contra-variant positions"?
Additionally, the second example appears to result in never and I am unsure if any additional configuration might be needed to make it work properly.