I want to annotate function, tat takes array with at least key "a"
and returns the same array shape with newly added key "x"
. I tried using type intersection like this:
/**
* @template T of array{a: string}
* @param T $p
* @return T&array{x: int}
*/
function addXToArray(array $p) {
$p['x'] = strlen($p['a']);
return $p;
}
$result = addXToArray(['a' => 'hello']);
This is obviously not the correct way, because PHPstan complains (on level 10 with "Treat PHPDoc types as certain"):
PHPDoc tag @return contains unresolvable type.
I use template T
because I need to preserve any other keys that may be present in the argument.
How do I correctly annotate the function?
I use template T because I need to preserve any other keys that may be present in the argument.
That's perhaps the hint needed here.
More specifically, you are using T
as an intersection type for @return with something that is not a type: array{} shape.
As has been outlined in phpstan / phpstan Array intersection support #4703 (github.com) the ampersand &
of an intersection type does not compute array shapes and likewise it does not the T
template in your example.
What you may expect from PHPStan according to ondrejmirtes in February 2024 is as following:
PHPStan WILL NOT add support for "array intersections" but WILL ADD support for "array shapes with extra keys with known type" using this syntax:
array{a: mixed, ...<array-key, mixed>}
(same as recently added in Psalm).Please follow this issue to get the updates: #8438 (github.com)