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