NonInvariantDocblockPropertyType
Emitted when a public or protected class property has a different docblock type to the matching property in the parent class.
<?php
class A {
/** @var null|string */
public $foo = 'hello';
}
class AChild extends A {
/** @var string */
public $foo;
}
Why this is bad
For non-typed properties, it can cause a type system violation when code written against the parent class reads or writes a value on an object of the child class.
If the child class widens the type then reading the value may return unexpected value that client code cannot deal with. If the child class narrows the type then code setting the value may set it to an invalid value:
<?php
function takesA(A $a) {
$a->foo = null; // this is valid for A
}
$child = new AChild();
takesA($child);
echo strlen($child->foo); // this is valid for AChild
Workarounds
You can either broaden the type or you could, in certain situations, use templates instead:
<?php
/**
* @template T of string|null
*/
abstract class A {
/** @var T */
public $foo = 'hello';
}
/**
* @extends A<string>
*/
class AChild extends A {
/** @var string */
public $foo;
}