Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Що таке intersection і DNF-типи і коли вони потрібні?

Intersection-тип A&B (PHP 8.1) - значення має відповідати всім перелічених типам одночасно. На практиці - об'єкт, що реалізує кілька інтерфейсів:

function process(Countable&Traversable $items): void
{
    echo count($items);
    foreach ($items as $item) { /* ... */ }
}

Раніше доводилося або обирати один інтерфейс і перевіряти другий вручну (instanceof), або створювати штучний інтерфейс CountableTraversable, який нічого не додає.

DNF-типи (Disjunctive Normal Form, PHP 8.2) - поєднання union і intersection: об'єднання груп, кожна з яких - перетин.

function save((Countable&ArrayAccess)|null $data): void {}
function cache((Stringable&JsonSerializable)|string $value): void {}

Правило DNF: перетини мають бути в дужках, і вони об'єднуються через |. Запис A&(B|C) недозволений - його треба переписати як (A&B)|(A&C).

Обмеження:

  • Перетин - лише з класів і інтерфейсів, не зі скалярів (int&string не має сенсу).
  • Дублювання й надлишкові типи ((A&B)|A) - помилка компіляції.

Коли потрібні:

  • Функція справді покладається на кілька незалежних можливостей об'єкта (лічильність і ітерація, рядкове представлення й серіалізація).
  • Бібліотеки з дрібними інтерфейсами-можливостями (принцип розділення інтерфейсів) - щоб вимагати рівно потрібні, а не один «товстий».
  • Моки в тестах: PHPUnit створює об'єкти-перетини MockObject&Service, і саме такий тип має змінна з моком.

Альтернатива: якщо одна й та сама комбінація інтерфейсів повторюється скрізь, можливо, це окреме поняття домену - і варто оголосити інтерфейс, що розширює обидва.

Докладніше в документації: Система типів PHP

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання