Features
List types
This release introduces a new list
type that represents continuous, integer-indexed arrays like ["red", "yellow", "blue"]
.
These arrays have the property $arr === array_values($arr)
, and represent a large percentage of all array usage in PHP applications.
A list
type is of the form list<SomeType>
, where SomeType
is any permitted union type supported by Psalm.
list
is a subtype ofarray<int, mixed>
list<Foo>
is a subtype ofarray<int, Foo>
.
List types show their value in a few ways:
/**
* @param array<int, string> $arr
*/
function takesArray(array $arr) : void {
if ($arr) {
// this index may not be set
echo $arr[0];
}
}
/**
* @psalm-param list<string> $arr
*/
function takesList(array $arr) : void {
if ($arr) {
// list indexes always start from zero,
// so a non-empty list will have an element here
echo $arr[0];
}
}
takesArray(["hello"]); // this is fine
takesArray([1 => "hello"]); // would trigger bug, without warning
takesList(["hello"]); // this is fine
takesList([1 => "hello"]); // triggers warning in Psalm
Bugfixes
Improved array refinement
Fixes #2156 - given a function that takes some user input (e.g. from $_GET
) Psalm can now fully typecheck the result
/**
* @param array<string, scalar> $arr
* @return array{id: int, name: string}
*/
function refine(array $arr) {
if (isset($arr['id'])
&& is_int($arr['id'])
&& isset($arr['name'])
&& is_string($arr['name'])
) {
return $arr;
}
throw new \Exception('Bad format');
}
Previously Psalm would infer the returned array above as array<scalar>
. Now it's inferred as a special type (that you cannot currently use in annotations) as array{id: int, name: string}<scalar>
- that is, an array where an arbitrary element is typed as scalar
, but where the specific offsets id
and name
have corresponding types.
You can play with the code here: https://psalm.dev/r/444930649e - change any of the strings to see what errors appear.
Other bugfixes
- more impure functions added - thanks @bugreportuser! (#2179, #2203))
- prevent class template types being wiped by creation of anonymous class (#2181)
- improve type handling of
__invoke
methods (#2184) - fix handling of
do...while(true)
with a break inside thedo
(#2183) - allow modification of cloned objects inside an immutable class (#2182)
- fix class aliasing bug (#2186)
- fixed argument order of
rar_entry_get
- thanks @villfa (#2189) - fixed arguments for
mysqli_real_connect
- thanks @jaydiablo (#2210) - fix bugs in templated property type support (#2208)
- Unused code elimination allow
UnusedPsalmSuppress
to operate on exception issues - thanks @bugreportuser! (#2211) - allow
array_diff
etc to have more than five params - thanks @Guuzen (#2201) - fix handling of callables that return
self
,static
(#2217)