Trasforma il tipo di unione in tipo di intersezione

C’è un modo per trasformare un tipo di unione in un tipo di intersezione:

type FunctionUnion = () => void | (p: string) => void type FunctionIntersection = () => void & (p: string) => void 

Vorrei applicare una trasformazione a FunctionUnion per ottenere FunctionIntersection

Vuoi che l’unione si intersechi? I tipi condizionali distributivi e l’ inferenza dai tipi condizionali possono farlo. (Non so come fare intersezione-a-unione però.) Ecco la magia del male:

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

Questo distribuisce l’unione U e la riconfeziona in una nuova unione in cui tutti i componenti sono in posizione contraria. Ciò consente al tipo di essere dedotto come intersezione I , come menzionato nel manuale:

Allo stesso modo, più candidati per la stessa variabile di tipo in posizioni controventuali provocano un tipo di intersezione da dedurre.


Vediamo se funziona.

Innanzitutto fammi parentesi con FunctionUnion e FunctionIntersection perché TypeScript sembra bind più strettamente l’unione / intersezione rispetto al ritorno della funzione:

 type FunctionUnion = (() => void) | ((p: string) => void); type FunctionIntersection = (() => void) & ((p: string) => void); 

test:

 type SynthesizedFunctionIntersection = UnionToIntersection // inspects as // type SynthesizedFunctionIntersection = (() => void) & ((p: string) => void) 

Sembra buono!

UnionToIntersection<> attenzione che in generale UnionToIntersection<> espone alcuni dettagli di ciò che TypeScript pensa sia un’unione reale. Ad esempio, boolean è apparentemente internamente rappresentato come true | false true | false , quindi

 type Weird = UnionToIntersection 

diventa

 type Weird = string & number & true & false 

Spero possa aiutare. In bocca al lupo!