What's the right way to fix the error generated by phpstan
for this sample code? The error message is:
Method Foo::foo() should return Child but returns Base.
<?php declare(strict_types = 1);
Interface MyI {
abstract function a(): self;
}
Class Base implements MyI {
public function a(): self {return $this;}
}
Class Child extends Base {
public function c(): self {return $this;}
}
Class Foo {
public function factory(): Child {
return new Child();
}
/**
* @return Child
*/
public function foo() /* note no return type */ {
return $this->factory()
->c()
->a();
}
}
One way to eliminate the error is to change the @return
to read:
/**
* @return Child | Base
*/
But I greatly dislike that because foo()
never returns an instance of Base
. The code only ever works with the derived class Child
. In fact, the interface and base classes are both in a library (dependency), so I mostly cannot even change that code.
I could re-implement a()
in my Child
class like this:
public function a(): Child {
parent::a();
return $this;
}
But that is also ugly, and worse, this is a toy example. In the real class, I'd have to re-implement many methods. Very bad.
You need @return static
for that: https://phpstan.org/r/42ee409c-ada2-44c9-a26d-6a85c2327bca
To learn about all different PHPDoc posibilities head to PHPStan documentation: