Open mistlog opened 3 years ago
Likewise, multiple candidates for the same type variable in contra-variant positions causes an intersection type to be inferred:
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
the clue is that we have to create function types and get intersection type from params.
we can only create union of function types from union, so the basic demo related to our problem is:
type Bar<T> = T extends (x: infer U) => void | ((x: infer U) => void )
? U
: never;
type T20 = Bar<(x: string) => void | ((x: string) => void)>; // string
type T21 = Bar<(x: string) => void | ((x: number) => void)>; // string & number = never
to make it clear:
type Bar<T> = T extends (x: infer U) => void | ((x: infer U) => void ) ? U : never;
type T20 = Bar<(x: {a: 1}) => void | ((x: {b:1}) => void)>; // { a: 1; } & { b: 1; }
step 1: create union of functions:
type function toFunctionUnion = (union) => ^{
if(union extends infer ItemType) {
return type (arg: ItemType) => any
} else {
return never
}
}
step 2: get intersection type from function params
export type function UnionToIntersection = (union) => ^{
if(toFunctionUnion<union> extends type (arg: infer ArgType) => any) {
return ArgType
} else {
return never
}
}
use typetype: