Тип соединения превращается в тип пересечения - PullRequest
1 голос
/ 04 мая 2020

Проблема

Я хочу создать фабрику, которая выполняет различные функции в зависимости от заданных параметров. Это может быть решено с помощью условных типов.

type DispatchConditional<TPayload> = TPayload extends undefined
  ? () => void
  : (payload: TPayload) => void;

Тип DispatchCondition может быть снабжен интерфейсом.

interface ActionDispatcher<TPayload> {
  dispatch: DispatchConditional<TPayload>;
}

Если я строю фабрику на основе приведенных выше определений, она сломается, если используется Union-Type. Каким-то образом тип объединения, определяемый payloadUnion(), становится Intersection-Type.

enter image description here

Вопрос

Какие корректировки я должен выполнить сделать, чтобы получить определение типа для метода dispatch, который поддерживает union-типы?

Playground

1 Ответ

3 голосов
/ 04 мая 2020

DispatchConditional - это распределенный условный тип . Это означает, что DispatchConditional<number | number[]> эквивалентно DispatchConditional<number> | DispatchConditional<number[]>, что, в свою очередь, будет объединением функций. А объединение функций может вызываться только при пересечении типа параметра (поскольку мы не знаем, какую функцию мы на самом деле получаем во время выполнения, мы должны предоставить параметры, которые работают с ОБА сигнатурами функций, что приводит к пересечению)

Простое решение состоит в том, чтобы отключить дистрибутивное поведение, поместив параметр типа в тип кортежа (распределение происходит только по параметрам открытого типа):


type DispatchConditional<TPayload> = [TPayload] extends [undefined]
  ? () => void
  : (payload: TPayload) => void;

Playground Link

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...