Sie möchten, dass sich die Vereinigung überschneidet? Verteilende bedingte Typen und Rückschlüsse auf bedingte Typen können dies tun. (Ich glaube nicht, dass es möglich ist, eine Kreuzung zu einer Vereinigung durchzuführen, sorry.) Hier ist die böse Magie:
type UnionToIntersection<U> =
(U extends any ? (k: U)=>void : never) extends ((k: infer I)=>void) ? I : never
Das verteilt die Gewerkschaft Uund verpackt sie in eine neue Gewerkschaft, in der sich alle Konstituenten in einer kontravarianten Position befinden. Dadurch kann der Typ als Schnittpunkt abgeleitet werden I, wie im Handbuch erwähnt:
Ebenso führen mehrere Kandidaten für dieselbe Typvariable in kontravarianten Positionen dazu, dass ein Schnittpunkttyp abgeleitet wird.
Mal sehen, ob es funktioniert.
Lassen Sie mich zuerst Ihre Klammern setzen FunctionUnionund FunctionIntersectionweil TypeScript die Vereinigung / Schnittmenge enger zu binden scheint als die Funktionsrückgabe:
type FunctionUnion = (() => void) | ((p: string) => void);
type FunctionIntersection = (() => void) & ((p: string) => void);
Testen:
type SynthesizedFunctionIntersection = UnionToIntersection<FunctionUnion>
Sieht gut aus!
Achten Sie darauf, dass im Allgemeinen UnionToIntersection<>einige Details darüber angezeigt werden, was TypeScript für eine tatsächliche Vereinigung hält. Zum Beispiel booleanwird anscheinend intern als true | false, so dargestellt
type Weird = UnionToIntersection<string | number | boolean>
wird
type Weird = string & number & true & false
was in TS3.6 + eifrig auf reduziert wird
type Weird = never
weil es unmöglich ist, einen Wert zu haben, der string und number und true und ist false .
Hoffentlich hilft das. Viel Glück!