tutorial react nodejs example ejemplos curso typescript

react - typescript tutorial



Transformar tipo de unión a tipo de intersección (2)

¿Hay una manera de transformar un tipo de unión en un tipo de intersección:

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

Me gustaría aplicar una transformación a FunctionUnion para obtener FunctionIntersection


¿Quieres unión a intersección? Los tipos condicionales distributivos y la inferencia de los tipos condicionales pueden hacer eso. (No creo que sea posible hacer una intersección a la unión, lo siento) Aquí está la magia malvada:

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

Eso distribuye el sindicato U y lo vuelve a empaquetar en un nuevo sindicato en el que todos los miembros están en una posición contraria. Eso permite inferir el tipo como una intersección I , como se menciona en el manual:

Del mismo modo, los candidatos múltiples para la misma variable de tipo en posiciones contra-variantes hacen que se infiera un tipo de intersección.

A ver si funciona.

Primero, permítame paréntesis entre FunctionUnion y FunctionIntersection porque TypeScript parece enlazar la unión / intersección más estrechamente que el retorno de la función:

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

Pruebas:

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

¡Se ve bien!

Tenga cuidado de que, en general, UnionToIntersection<> exponga algunos detalles de lo que TypeScript piensa que es una unión real. Por ejemplo, boolean aparentemente se representa internamente como true | false true | false , entonces

type Weird = UnionToIntersection<string | number | boolean>

se convierte en

type Weird = string & number & true & false

Espero que ayude. ¡Buena suerte!


Si está tratando de transformar una matriz en una intersección , mapear la matriz de antemano hará que la unión de la matriz resultante tenga un orden incorrecto .

Esto puede no importar si el orden de intersección resultante no importa, pero si lo hace, la respuesta anterior no funcionará.

A continuación se admiten matrices hasta el índice de 9 , que se pueden ampliar manualmente si necesita una repetición más prolongada.

type Idx<T extends any, K extends keyof any, Yes> = T extends Record<K, any> ? T[K] & Yes : unknown type ArrayToIntersection<T extends any[]> = Idx<T, ''0'', Idx<T, ''1'', Idx<T, ''2'', Idx<T, ''3'', Idx<T, ''4'', Idx<T, ''5'', Idx<T, ''6'', Idx<T, ''7'', Idx<T, ''8'', Idx<T, ''9'', unknown>>>>>>>>>> // Usage: => 1 & 2 & 3 & 4 type Result = ArrayToIntersection<[1, 2, 3, 4]>