Intersection types, a new addition to PHP type system that allows us to constraint a value to satisfy multiple types at same time.
Until PHP 8.0, we could only define a single type as parameter/return/property type. On PHP 8.1, we got Union type, which allowed us to restrict a value to satisfy either type X OR type Y. Intersection type is exactly the opposite of that. It allows us to restrict a value to satisfy both type X AND type Y.
<?php
interface X {}
interface Y {}
class A {
// UNION type, $param must be either X or Y
public function foo(X|Y $param) {}
// INTERSECTION type, $param must be both X and Y
public function bar(X&Y $param){}
}
Don't worry, intersection type can be used in return type and typed properties too.
Full example:
<?php
interface X {}
interface Y {}
class Something implements X, Y {}
class AnotherThing implements X {}
class User {
public X&Y $xAndY;
public function foo (X&Y $param): X&Y{
return $param;
}
}
$something = new Something;
$anotherThing = new AnotherThing;
$user = new User;
$user->xAndY = $something; // works
$user->xAndY = $anotherThing; // doesn't work, because anotherThing is not both X and Y
$user->foo($something); // works, because something is both X and Y
$user->foo($anotherThing); // doesn't work
// returns types follow the same rule, foo() can only return value that is both X and Y
Restrictions:
Inheritance rules:
interface A {}
interface B {}
class Test {
public function foo(A&B $param) {}
public function bar(A $param) {}
}
class AnotherTest extends Test {
public function foo(A $param) {} // Allowed, can remove type
public function bar(A&B $param) {} // Forbidden, cannot add type
}
interface A {}
interface B {}
class Test {
public function foo(): A {}
public function bar(): A&B {}
}
class AnotherTest extends Test {
public function foo(): A&B {} // Allowed, can add type
public function bar($param): A {} // Forbidden, cannot remove type
}
For reflection purpose, ReflectionIntersectionType class has been introduced.
RFC: https://wiki.php.net/rfc/pure-intersection-types
As I hoped on my union type post, We got intersection type as well. Maybe we are very close to get our hands on type alias feature too. Should I start dreaming about having generics? Faith is all we got.
Till then, keep your code type safe.
Write comment about this article: