packagist vimeo/psalm 3.6.0
Support list array type

latest releases: 5.x-dev, dev-master, dev-isTypeContainedByType_flags...
4 years ago

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 of array<int, mixed>
  • list<Foo> is a subtype of array<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 the do (#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)

Don't miss a new psalm release

NewReleases is sending notifications on new releases.