Intersection Types in PHP 8.1

Intersection Types in PHP 8.1

Since PHP 8.0, we can use union types which allows providing two or more types for parameters, return values, and properties. The given value should be one of the specified types.

Since PHP 8.1, intersection types can be used. It requires the value to be all the specified class and interface types. We can specify any number of types which are combined by ampersand (&) using the syntax:

class_1&class_2&interface_1&interface_2&...&class_n&interface_n

Intersection types are allowed anywhere types are accepted: parameters, return values, and properties.

Storage.php

<?php

class Storage
{
    private ArrayAccess&Countable $container;

    public function getContainer(): Countable&ArrayAccess
    {
        return $this->container;
    }

    public function setContainer(Countable&ArrayAccess $container): void
    {
        $this->container = $container;
    }
}

For example, with intersection types now possible to check if class implements both ArrayAccess and Countable interfaces. Parameter $container should be an instance of the class that implements both specified interfaces (e.g. CountableArrayObject class). Passing any instance of the class that does not implement both interfaces gives a fatal error.

CountableArrayObject.php

<?php

class CountableArrayObject implements ArrayAccess, Countable
{
    public function offsetExists(mixed $offset): bool { return false; }
    public function offsetGet(mixed $offset): mixed { return null; }
    public function offsetSet(mixed $offset, mixed $value): void {}
    public function offsetUnset(mixed $offset): void {}
    public function count(): int { return 0; }
}

Combination with union types

Since PHP 8.2, intersection types can be used together with union types. This combination is called DNF types.

Nullable types

PHP allows using nullable types (e.g. ?string or string|null). Since PHP 8.2, intersection types can be used together with nullable type notation by defining DNF type.

Class and interface types

Only classes and interfaces can be used as part of the intersection types. Scalar types (bool, int, float, string), compound types (array, object, callable, iterable), void, mixed, never, and other types are not allowed. For example, int&float is illegal.

Duplicate types

A class or interface cannot be used more than one time as part of the intersection types. This means that we cannot define type declarations such as ArrayAccess&Countable&ArrayAccess. It will produce a fatal error.

Leave a Comment

Cancel reply

Your email address will not be published.