psalm
psalm copied to clipboard
Pushing to a list element changes the type of the list to `non-empty-array`
How to iterate over a list and modify each entry without psalm thinking we're modifying the list to a non-empty-array<int, mixed> ?
https://psalm.dev/r/d86080eff8
class Foo
{
/** @var list<array> */
public $list = array();
public function someMethod() : void
{
/** @var mixed $v */
foreach ($this->list as $i => $v) {
self::modifyItem($i, $v);
}
}
public function modifyItem(int $i, mixed $v) : void
{
if (!array_key_exists($i, $this->list)) {
throw new InvalidArgumentException('unknown key');
}
$this->list[$i][] = array();
}
}
I found these snippets:
https://psalm.dev/r/fd8cfec9ab
<?php
class Foo
{
/** @var list<mixed> */
public $list = array();
public function someMethod() : void
{
/** @var mixed $v */
foreach ($this->list as $i => $v) {
self::modifyItem($i, $v);
}
}
public function modifyItem(int $i, mixed $v) : void
{
$this->list[$i] = $v;
}
}
Psalm output (using commit 9520223):
ERROR: PropertyTypeCoercion - 18:9 - $this->list expects 'list<mixed>', parent type 'non-empty-array<int, mixed>' provided
I'd just validate that the index exists: https://psalm.dev/r/9d49161cec
I found these snippets:
https://psalm.dev/r/9d49161cec
<?php
class Foo
{
/** @var list<mixed> */
public $list = array();
public function someMethod() : void
{
/** @var mixed $v */
foreach ($this->list as $i => $v) {
self::modifyItem($i, $v);
}
}
public function modifyItem(int $i, mixed $v) : void
{
if (!array_key_exists($i, $this->list)) {
throw new InvalidArgumentException('unknown key');
}
$this->list[$i] = $v;
}
}
Psalm output (using commit 9520223):
No issues!
@weirdan thanks / seems obvious
not immediately working in my real-world use-case... will spend a bit more time on it.
@weirdan
https://psalm.dev/r/d86080eff8
public function modifyItem(int $i, mixed $v) : void
{
if (!array_key_exists($i, $this->list)) {
throw new InvalidArgumentException('unknown key');
}
$this->list[$i][] = array(); // $this->list expects 'list<array<array-key, mixed>>', parent type 'non-empty-array<int, array<array-key, mixed>>' provided
}
thoughts?
I found these snippets:
https://psalm.dev/r/d86080eff8
<?php
class Foo
{
/** @var list<array> */
public $list = array();
public function someMethod() : void
{
/** @var mixed $v */
foreach ($this->list as $i => $v) {
self::modifyItem($i, $v);
}
}
public function modifyItem(int $i, mixed $v) : void
{
if (!array_key_exists($i, $this->list)) {
throw new InvalidArgumentException('unknown key');
}
$this->list[$i][] = array();
}
}
Psalm output (using commit 9520223):
ERROR: PropertyTypeCoercion - 21:9 - $this->list expects 'list<array<array-key, mixed>>', parent type 'non-empty-array<int, array<array-key, mixed>>' provided
possibly related #10449