psalm
psalm copied to clipboard
Disjointed array shape blocks non-empty-array
https://psalm.dev/r/d92d35a175
Is there a correct way of asserting to Psalm that array{A?: 'A', B?: 'B'} is in fact non-empty-array?
I found these snippets:
https://psalm.dev/r/d92d35a175
<?php
/**
* @return non-empty-array<string, string>|true
*/
function run_count(): array|bool
{
$out = [];
if (rand(0,1)) {
$out['A'] = 'A';
}
if (rand(0,1)) {
$out['B'] = 'B';
}
return count($out) === 0 ? true : $out;
}
/**
* @return non-empty-array<string, string>|true
*/
function run_empty(): array|bool
{
$out = [];
if (rand(0,1)) {
$out['A'] = 'A';
}
if (rand(0,1)) {
$out['B'] = 'B';
}
return empty($out) ? true : $out;
}
/**
* @return non-empty-array<string, string>|true
*/
function run_equality(): array|bool
{
$out = [];
if (rand(0,1)) {
$out['A'] = 'A';
}
if (rand(0,1)) {
$out['B'] = 'B';
}
return $out == [] ? true : $out;
}
Psalm output (using commit 3c90054):
INFO: LessSpecificReturnStatement - 17:16 - The type 'array{A?: 'A', B?: 'B'}|true' is more general than the declared return type 'non-empty-array<string, string>|true' for run_count
INFO: MoreSpecificReturnType - 4:16 - The declared return type 'non-empty-array<string, string>|true' for run_count is more specific than the inferred return type 'array{A?: 'A', B?: 'B'}|true'
INFO: LessSpecificReturnStatement - 35:16 - The type 'array{A?: 'A', B?: 'B'}|true' is more general than the declared return type 'non-empty-array<string, string>|true' for run_empty
INFO: MoreSpecificReturnType - 22:16 - The declared return type 'non-empty-array<string, string>|true' for run_empty is more specific than the inferred return type 'array{A?: 'A', B?: 'B'}|true'
INFO: LessSpecificReturnStatement - 52:16 - The type 'array{A?: 'A', B?: 'B'}|true' is more general than the declared return type 'non-empty-array<string, string>|true' for run_equality
INFO: MoreSpecificReturnType - 39:16 - The declared return type 'non-empty-array<string, string>|true' for run_equality is more specific than the inferred return type 'array{A?: 'A', B?: 'B'}|true'
Also fails if the outputs are fully independent https://psalm.dev/r/c39f3c8c05
I found these snippets:
https://psalm.dev/r/c39f3c8c05
<?php
/**
* @return non-empty-array<string, string>|true
*/
function run_count(): array|bool
{
if (rand(0,1)) {
return ['A' => 'A'];
}
if (rand(0,1)) {
return ['B' => 'B'];
}
return true;
}
Psalm output (using commit 3c90054):
INFO: MoreSpecificReturnType - 4:16 - The declared return type 'non-empty-array<string, string>|true' for run_count is more specific than the inferred return type 'array{A?: 'A', B?: 'B'}|true'
Not possible currently, see https://github.com/vimeo/psalm/issues/9413