Using array shape as custom type in PHPStan
· 2 min read
My friend Beau Simensen recently asked on Mastodon if it is possible to pass an array shape as a type to a function?
Good question. And the answer is yes. Here's how it works.
Assuming, you want PHPStan to check this code and make sure that the $array
parameter passed to the function has both required array keys min
and max
set:
function test(array $array): bool
{
return $array['max'] < $array['min'];
}
We can define a global type alias in PHPStan in the configuration file like this:
parameters:
typeAliases:
MyArrayType: 'array{min: int, max: int}'
Now we can add the MyArrayType
type alias to the function to help PHPStan better understand the situation:
/** @param MyArrayType $array */
function test(array $array): bool
{
return $array['max'] < $array['min'];
}
Thanks to the custom type alias, PHPStan is able to run the following checks:
- Does the function internally only use the keys exposed by the
MyArrayType
type? In case we have a typo in the code and try to access themat
key instead of themax
key, PHPStan will detect this issue:
Offset 'mat' does not exist on array{min: int, max: int}.
🪪 offsetAccess.notFound
- Does the caller provide the defined array keys of the
MyArrayType
type when calling the function? In case we pass a key that is not configured by the custom type definition, PHPStan will tell us:
Parameter #1 $array of function test expects array{min: int, max: int}, array{mat: 5} given.
🪪 argument.type
💡 Array does not have offset 'min'.
Type aliases greatly assist PHPStan in comprehending "non-class" structures within your code, enabling it to perform various validations.