How would one Type Hint a static singleton-returning method on an abstract class, which returns instances of the extending called classes?
For example, let's look at the following code:
<?php
abstract class Foo {
/** @return Foo */
public function init() {
static $instance;
if ( is_null($instance) ) {
$class = get_called_class();
$instance = new $class();
}
return $instance;
}
}
class Bar extends Foo {
public $name = "Bar name";
}
class Baz extends Foo {
public $age = 42;
}
My intention is for tools such as PhpStorm to understand that Bar::init()
returns an object of type Bar
and that Baz::init()
returns an object of type Baz
. Thus, for example, objects created from the Baz::init()
method would auto-complete the name
property but not the age
property.
Obviously the current type hint @return Foo
is wrong as the method will never return an object instance of an abstract class.
So @return static
will work in this case for PHPStorm. It is the easiest option and will provide what you are looking for.
Optionally you can use the @method
annotation against the class although this is very manual and needs to be done for each class. There is another strange thing with this method in PHPStorm where if you navigate to the init()
method (ctrl+click or w/e) it will navigate to this annotation first. However this is how that looks:
/**
* @method Bar init()
*/
class Baz extends Foo
{
}
Where optionally as a final resort--and I really don't think you will need it but its here for completeness. Extend the method and add your return annotation as you would a normal method.
/**
* @return Baz
*/
public function init()
{
return parent::init();
}