Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support reduced type inferring from Collection::reduce #154

Open
laurentmuller opened this issue May 21, 2024 · 3 comments
Open

Support reduced type inferring from Collection::reduce #154

laurentmuller opened this issue May 21, 2024 · 3 comments

Comments

@laurentmuller
Copy link

Plugin should add capability to infer reduced type from Collection::reduce based on assertions in a callback, similarly as Psalm currently does for array_reduce.

This is the the same as #58.

This is the current annotation: https://github.com/doctrine/collections/blob/b1f7c33ebb2d73a4860d6b65a11b9662b9904ebd/src/ReadableCollection.php#L241

For example, the following code must not raise any error:

class Item {
    public float $value = 0.0;
}

/** 
 * @param Collection<array-key, Item> $collection
 */
function foo(Collection $collection): float {
    return $collection->reduce(
        fn (float $carry, Item $item): float => $carry + $item->value,
        0.0
    );
}

See example: https://psalm.dev/r/80735e2f8d

The Collections.phpstub file must updated to reflect changes.

Copy link

I found these snippets:

https://psalm.dev/r/80735e2f8d
<?php
/**
 * @psalm-template TKey of array-key
 * @psalm-template T
 */
interface Collection
{
   /**
     * Applies iteratively the given function to each element in the collection,
     * so as to reduce the collection to a single value.
     *
     * @psalm-param Closure(TReturn|TInitial, T):TReturn $func
     * @psalm-param TInitial $initial
     *
     * @psalm-return TReturn|TInitial
     *
     * @psalm-template TReturn
     * @psalm-template TInitial
     */
    public function reduce(Closure $func, mixed $initial = null): mixed;
}

class Item {
    public float $value = 0.0;
}

/** 
 * @param Collection<array-key, Item> $collection
 */
function foo(Collection $collection): float {
    return $collection->reduce(
        fn (float $carry, Item $item): float => $carry + $item->value,
        0.0
    );
}
Psalm output (using commit 16b24bd):

No issues!

@laurentmuller
Copy link
Author

It's correct. But no definition exist for the reduce() function in the collections stub.

@laurentmuller
Copy link
Author

FYI:

Please see how is implemented in phpstan/phpstan-doctrine v1.5.5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant