Ответ 1
Вы хотите, чтобы союз до пересечения? Распределительные условные типы и вывод из условных типов могут сделать это. (Не думаю, что возможно сделать пересечение в союз, хотя, извините) Здесь злая магия:
type UnionToIntersection<U> =
(U extends any ? (k: U)=>void : never) extends ((k: infer I)=>void) ? I : never
Это распределяет союз U
и переупаковывает его в новый союз, где все составляющие находятся в противоположном положении. Это позволяет выводить тип как пересечение I
, как упомянуто в справочнике:
Аналогично, несколько кандидатов на одну и ту же переменную типа в противоположных позициях приводят к выводу типа пересечения.
Давайте посмотрим, работает ли это.
Сначала позвольте мне заключить в скобки ваши FunctionUnion
и FunctionIntersection
потому что TypeScript, кажется, связывает объединение/пересечение более тесно, чем возврат функции:
type FunctionUnion = (() => void) | ((p: string) => void);
type FunctionIntersection = (() => void) & ((p: string) => void);
Тестирование:
type SynthesizedFunctionIntersection = UnionToIntersection<FunctionUnion>
// inspects as
// type SynthesizedFunctionIntersection = (() => void) & ((p: string) => void)
Выглядит хорошо!
Будьте осторожны, что в общем случае UnionToIntersection<>
раскрывает некоторые детали того, что TypeScript считает действительным объединением. Например, boolean
внутренне представляется как true | false
true | false
, так
type Weird = UnionToIntersection<string | number | boolean>
становится
type Weird = string & number & true & false
Надеюсь, это поможет. Удачи!