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

Force variadic to have integer keys #10034

Closed
mhsdesign opened this issue Oct 19, 2023 · 5 comments
Closed

Force variadic to have integer keys #10034

mhsdesign opened this issue Oct 19, 2023 · 5 comments

Comments

@mhsdesign
Copy link

mhsdesign commented Oct 19, 2023

Feature request

I usually like to have collections with spreads in the constructor:

class Thing
{
}

class Things
{
    /** @var array<int, Thing> */
    private array $things;

    /**
     * @param Thing ...$things
     */
    public function __construct(
        Thing ...$things
    ) {
        $this->things = $things;
    }

    /** @return array<int, Thing> */
    public function toArray(): array
    {
        return $this->things;
    }
}

and in strict cases i want to enforce that $things should be a integer list of Thing - so /** @var array<int, Thing> */ or /** @var list<Thing> */.

The problem is that with php 8.0 variadic can also have string keys due to named arguments:

new Things(foo: new Thing());

that causes phpstan to report on php >= 8.0

https://phpstan.org/r/ddd461b8-16a1-4b5e-aa62-731c7ff6678b

Property Things::$things (array<int, Thing>) does not accept array<int|string, Thing>.

but for most cases i dont want to allow this behavior and instead like to rely on a simple integer list.

For those cases i like to declare in the constructor that ...$things must have integer keys. There currently seems no syntax for this (neither psalm nor phpstan)

Fictional ugly example:

    /**
     * @param Thing ...$things
     * @phpstan-param-variadic-key int ...$things
     */
    public function __construct(
        Thing ...$things
    ) {
        $this->things = $things;
    }

Workarounds: Use array_values on the array before assigning it or dont be so strict about the key type.

Did PHPStan help you today? Did it make you happy in any way?

It really feels like a game and its fun to level up ;)

@mad-briller
Copy link
Contributor

you can use @no-named-arguments:

https://phpstan.org/r/ba5578cd-d0d3-426a-8bbd-9de6bcb8ffc3

@mad-briller
Copy link
Contributor

it's worth noting however that phpstan does not seem to enforce this at the callsite:

https://phpstan.org/r/34061038-185a-4f61-8740-eb72a9351ed3

dunno if that's worth re-opening the issue @ondrejmirtes ?

@ondrejmirtes
Copy link
Member

There is already #5968

@mhsdesign
Copy link
Author

Wow thanks for your quick responses that was fast.

Copy link

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 20, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants