Термин распределительный относится к тому, как типы объединения должны обрабатываться при выполнении операций на уровне типа (например, keyof
или отображаемых типов).
- Нераспространяющие (по умолчанию) операции применяются к свойствам, которые существуют на каждом члене объединения.
- Распределительные операции применяются к всем элементам union отдельно.
Давайте рассмотрим пример.
type Fruit =
| { species: 'banana', curvature: number }
| { species: 'apple', color: string }
Предположим, что по какой-то причине вы хотите знать все возможные ключи, которые могут существовать на Fruit
.
Не распространяемый
Ваша интуиция может подсказать вам, что нужно сделать:
type KeyOfFruit = keyof Fruit; // "species"
Однако это даст вам только те свойства, которые существуют на каждый член союза. В нашем примере species
- единственное общее свойство, разделяемое всеми Fruit
.
Это то же самое, что применить keyof
к объединению двух типов.
keyof ({ species: 'banana', curvature: number } | { species: 'apple', color: string })
Распределительный
При распространении операция не выполняется для только общих свойств. Вместо этого это делается для каждого члена союза отдельно . Затем результаты складываются.
type DistributedKeyOf<T> =
T extends any
? keyof T
: never
type KeyOfFruit = DistributedKeyOf<Fruit>; // "species" | "curvature" | "color"
В этом случае TypeScript применяет keyof
к каждому члену объединения и суммирует результаты.
keyof { species: 'banana', curvature: number } | keyof { species: 'apple', color: string }