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

Question: Is there a way to assert that an array key exists in a given array? #8785

Open
boesing opened this issue Nov 28, 2022 · 4 comments

Comments

@boesing
Copy link
Contributor

boesing commented Nov 28, 2022

Hey there,

I've tried something like this but I don't get a working example:

https://psalm.dev/r/74f4a57aaa

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/74f4a57aaa
<?php

/**
 * @template TKey of array-key
 * @template TValue
 * @param TKey $key
 * @param array<array-key,TValue> $array
 * @psalm-assert array<TKey,TValue> $array
 */
function assertArrayKeyExists(string|int $key, array $array): void
{}

/** @var array<array-key,non-empty-string> $foo */
$foo = [];

assertArrayKeyExists('bar', $foo);
assertArrayKeyExists('baz', $foo);

/** 
 * expected array{bar:non-empty-string, baz:non-empty-string}
 * @psalm-trace $foo 
 */
Psalm output (using commit c3cc906):

INFO: UnusedParam - 10:42 - Param $key is never referenced in this method

INFO: UnusedParam - 10:54 - Param $array is never referenced in this method

ERROR: DocblockTypeContradiction - 17:1 - Cannot resolve types for $foo - docblock-defined type array<'bar', non-empty-string> does not contain array<'baz', non-empty-string>

INFO: Trace - 22:4 - $foo: array<'baz', non-empty-string>

@orklah
Copy link
Collaborator

orklah commented Nov 30, 2022

I remember looking for something like this for another issue, unfortunately, the internal handling of that is pretty complex in Psalm. We have an HasArrayKey assertion and also an ArrayKeyExists one. If I remember correctly, the HasArrayKey applies to a specific variable and has a $key property for the name of the key that exists, and the ArrayKeyExists directly applies to the $a['someKey'] identifier.
I'm not really sure why both are needed, I tried to drop ArrayKeyExists but reconciliation broke and I wasn't exactly sure what was going on.

If we want to progress on this, we would probably first need to do exactly that. And then have some sort of syntax that allows to assert dynamic keys (like in your example).

@VincentLanglet
Copy link
Contributor

I remember looking for something like this for another issue, unfortunately, the internal handling of that is pretty complex in Psalm

Do you mean psalm/psalm-plugin-phpunit#114 ?

@orklah
Copy link
Collaborator

orklah commented Dec 1, 2022

Yep, that's the one (though we were using V4 style assertion in Psalm's internal, so my explanation there is a bit outdated)

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

No branches or pull requests

3 participants