I've been working recently with classes that initialize themselves from an array of data, and have typed properties which are set with values retrieved from the array.
The properties are typed, which means PHP will throw a TypeError if anything besides the specified type is passed in.
However, PhpStorm appears to be propogating the mixed
type from the array access to the class property.
I'm struggling to explain it in words, so here's an example script:
<?php
class TestClass
{
public readonly string $myString;
public readonly int $myInt;
public readonly array $myArray;
public function __construct(array $src)
{
$this->myString = $src['stringVal'];
$this->myInt = $src['intVal'];
$this->myArray = $src['array'];
}
}
$arr = [
'stringVal' => 123,
'intVal' => "I am a string",
'array' => null,
];
$x = new TestClass($arr); // throws TypeError from within the constructor
$y = new TestClass($x->myInt); // PhpStorm doesn't see anything wrong with this???
You can see that there are types on all 3 of the properties. You can look at the script and see that it will fail. The script as written throws a TypeError exactly as you'd expect when it tries to set $this->myString
.
However, if I hover over any of the class properties, PhpStorm is adding the mixed
type to the property:
Since PhpStorm is treating all of the properties as "x or mixed", it doesn't see anything wrong with the obviously incorrect last line of the script, where we're trying to pass an int to the constructor, which requires an array:
How can I get PhpStorm to stop inferring mixed
on these properties?
Update: it's not only mixed
coming from an array, it seems that PhpStorm is just assuming that whatever happens in the constructor is valid, regardless of the types on the properties(?)
Another example:
class TestClass2
{
public readonly int $myInt;
public function __construct()
{
$this->myInt = "hello world";
}
}
The constructor throws a TypeError, again just as you'd expect. But PhpStorm seems content to assume that the property will accept a string:
I filed a bug report to JetBrains, and they gave me the following workaround:
As a workaround, you can either mark the file with
declare(strict_types=1);
or enable the PHP | Type compatibility | Strict type checking rules violation: Enable for all files.
In my case, the code inspection setting was most appropriate and solved the issue for me.