Psalm: Generic Iterable Parameter with Splat Loses inner Type

Created on 16 Feb 2020  路  4Comments  路  Source: vimeo/psalm

https://psalm.dev/r/b83276837c

Here is an example showing two different join methods one that takes an a variadic number of args via the splat syntax, and the other just accepting an array. The join method simply takes an iterable of iterables and joins them together into one iterable, very similar to array_merge.

e.g.

join([1,2,3], [4,5,6]) == [1,2,3,4,5,6]

It seems as though, when I typehint with the splat syntax for the varargs, the resulting iterable from join doesn't maintain the inner type of T, and defaults to mixed as shown in the MixedAssignment warning.

However, when I don't use the varargs and just accept an array, the inner type is maintained.

I've read the docs a few times and didn't see any examples that could guide me through and already have checked the open/closed Github issues and didn't seem to find anyone else stumbling on my specific issue.

I apologize in advance if this is just me not understanding the proper docblock syntax :(.

bug

Most helpful comment

From one Brooklynite to another, thanks!

All 4 comments

I found these snippets:


https://psalm.dev/r/b83276837c

<?php

/**
 * @template T
 * @param iterable<T> ...$iterators
 * @return iterable<T>
 */
function joinBySplat(iterable ...$iterators): iterable {
    foreach ($iterators as $iter) {
        foreach ($iter as $value) {
            yield $value;
        }
    }
}

/**
 * @template T
 * @param iterable<iterable<T>> $iterators
 * @return iterable<T>
 */
function joinByIter(iterable $iterators): iterable {
    foreach ($iterators as $iter) {
        foreach ($iter as $value) {
            yield $value;
        }
    }
}

/** @return iterable<iterable<int>> */
function genIters(): iterable {
    yield [1,2,3];
    yield [4,5,6];
}

$values = joinBySplat(...genIters());
foreach ($values as $value) {
    echo $value;
}

$values = joinByIter(genIters());
foreach ($values as $value) {
    echo $value;
}
Psalm output (using commit d3bfb96):

INFO: MixedAssignment - 36:21 - Cannot assign $value to a mixed type

INFO: MixedArgument - 37:7 - Argument 1 of echo cannot be mixed, expecting string

whoa, awesome!!! Thanks for the quick turn around!

Btw, I've been playing around with psalm over the weekend, and I'm absolutely blown away at how well this works. I feel like I'm coding in php 9 with psalm, some very very neat stuff.

From one Brooklynite to another, thanks!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

zerkms picture zerkms  路  3Comments

muglug picture muglug  路  3Comments

Pierstoval picture Pierstoval  路  3Comments

ErikBooijCB picture ErikBooijCB  路  4Comments

ADmad picture ADmad  路  3Comments