Skip to content

Question: How does UnionToIntersection helper work #27907

Closed
@cevek

Description

@cevek

Can anybody to explain how does this black evil magic work?

type UnionToIntersection<U> =
	(U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never

If I simplify (U extends any ? (k: U) => void : never) -> (a: U)=>void)
it starts to work just as expected (No intersection)

type UnionToIntersection<U> = ((a: U)=>void) extends ((k: infer I) => void) ? I : never
type F = UnionToIntersection<'A' | 'B'> // A | B

Distributive conditional types iterate over union and apply all union units to this condition
But somehow this condition (U extends any ? (k: U) => void : never) tells ts that we don't need to iterate over union items in the outer extends but in the inner extends and make new type: ((k: 'A') => void) | ((k: 'B') => void)

so after all this combinations ts would work with type like this:

type H = (((k: 'A') => void) | ((k: 'B') => void)) extends (k: infer I)=>void ? I : never;

And return 'A' & 'B' because function argument is contra-variant

So question why outer extends doesn't iterate union?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions