1

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?

3
  • 1
    Educated guess: @return array{a: string, x: int} phpstan.org/r/7e983392-a5bb-47b9-94bf-5d9fc2697b5b -- for details see the answer Commented Jan 19 at 16:52
  • 1
    You probably want to take a look at Offset access, too. Not exactly a fit on your array-intersecting but this or the new PHP property hooks may give you something. Commented Jan 19 at 17:02
  • 1
    @hakre Thank You for useful links, I am going to study them :-) You helped me a lot. Commented Jan 19 at 17:07

1 Answer 1

2

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)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.