最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

php - Specifying keys in array shape in PHPstan - Stack Overflow

programmeradmin3浏览0评论

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 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?

Share Improve this question asked Jan 19 at 16:02 Roman HockeRoman Hocke 4,2391 gold badge21 silver badges35 bronze badges 3
  • 1 Educated guess: @return array{a: string, x: int} phpstan.org/r/7e983392-a5bb-47b9-94bf-5d9fc2697b5b -- for details see the answer – hakre 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. – hakre Commented Jan 19 at 17:02
  • 1 @hakre Thank You for useful links, I am going to study them :-) You helped me a lot. – Roman Hocke Commented Jan 19 at 17:07
Add a comment  | 

1 Answer 1

Reset to default 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)

发布评论

评论列表(0)

  1. 暂无评论