psalm
psalm copied to clipboard
Use a parameter value as part of an assert's type?
I guess this is something like generics but I can't quite get my head around it
I want to write an assertion function (possibly to contribute back to a library) that checks an array has specific keys ONLY but am not sure how I can possibly annotate it?
Is there a way to tell psalm that the shape of the array is dictated by the param to the assertion?
https://psalm.dev/r/1f919a9f94
I found these snippets:
https://psalm.dev/r/1f919a9f94
<?php
/**
* @param list<array-key> $expected
*
* what can I psalm-assert here?
*/
function assertArrayKeys(array $expected, array $input): void
{
// real impl will be more complex of course
$actual = array_keys($input);
sort($expected);
sort($actual);
assert($expected === $actual);
}
/**
* @param array{foo: mixed, ...} $f
* @return array{foo: mixed}
*/
function receive(array $f) {
assertArrayKeys(['foo'], $f);
return $f;
}
Psalm output (using commit 729c0ba):
ERROR: InvalidReturnStatement - 26:12 - The inferred type 'array{foo: mixed, ...<array-key, mixed>}' does not match the declared return type 'array{foo: mixed}' for receive
ERROR: InvalidReturnType - 22:12 - The declared return type 'array{foo: mixed}' for receive is incorrect, got 'array{foo: mixed, ...<array-key, mixed>}'