Search code examples
phptypingstatic-typingpsalm-php

How to create intersection type of arrays


A simplification of what I'm trying to implement is the following:

<?php

/**
 * @psalm-type Foo=array{foo: string}
 * @psalm-type Bar=array{bar: int}
 */

/**
 * @param Foo&Bar $v
 */
function acceptFooAndBar(array $v): void {
    echo sprintf('%s %d', $v['foo'], $v['bar']);
}

acceptFooAndBar(['foo' => 'f', 'bar' => 42]);

https://psalm.dev/r/d08f3ea0d1

In short: I'm trying to type a function that accepts an array that is an intersection of 2 other @psalm-types. That is: an array has fields from both array types (those are unique and are guaranteed to be different).

This code as expected - does not type check:

ERROR: InvalidDocblock - 9:11 - Intersection types must all be objects, Psalm\Type\Atomic\ObjectLike provided in docblock for acceptFooAndBar

Is there really no way but to stick to runtime assertions/checks?

Important: this question is strictly about static typing, I understand you can check it in runtime.


Solution

  • I reported it as a bug https://github.com/vimeo/psalm/issues/3095 and it was fixed at https://github.com/vimeo/psalm/commit/09663b593895fb7e6a0ed789dfad11363999bfea

    So now it type-checks properly.