vimeo/psalm

Merging of objects with defined properties should yield objects with union of properties

Open

#2.115 geöffnet am 10. Sept. 2019

Auf GitHub ansehen
 (3 Kommentare) (0 Reaktionen) (1 zugewiesene Person)PHP (668 Forks)batch import
Help wantedenhancement

Repository-Metriken

Stars
 (5.369 Stars)
PR-Merge-Metriken
 (Durchschn. Merge 3T 12h) (5 gemergte PRs in 30 T)

Beschreibung

Similar to https://github.com/vimeo/psalm/issues/2105 (declined), so I'm throwing this here for evaluation.

It seems like there's an issue with merging two objects in a declaration like object{foo: string}&object{bar: string}:

<?php

/** @psalm-return object{field1: string}&object{field2: string} */
function combine(object $a, object $b) : object
{
    return (object) \array_merge((array) $a, (array) $b);
}

$a = new \stdClass;
$a->field1 = 'a';

$b = new \stdClass;
$b->field2 = 'b';

echo combine($a, $b)->field1;

This reports (https://psalm.dev/r/a0a96475ab):

Psalm output (using commit deb36e8):

INFO: MixedArgument - 15:6 - Argument 1 of echo cannot be mixed, expecting string

If instead of accessing field1 I do access field2, then no errors occur (https://psalm.dev/r/e01ed36829). Maybe only the second declaration in the intersection is taken into account?

Similarly to the above, using generic types A and B and an intersection of A&B leads to inferring mixed (https://psalm.dev/r/76313da9d0):

<?php

/**
 * @psalm-template A of object
 * @psalm-template B of object
 * @psalm-param A $a
 * @psalm-param B $b
 * @psalm-return A&B
 */
function combine(object $a, object $b) : object
{
    return (object) \array_merge((array) $a, (array) $b);
}

$a = new \stdClass;
$a->field1 = 'a';

$b = new \stdClass;
$b->field2 = 'b';

echo combine($a, $b)->field2;
Psalm output (using commit deb36e8):

INFO: MixedArgument - 21:6 - Argument 1 of echo cannot be mixed, expecting string

Contributor Guide