Об этом спрашивали снова и снова, но ответы немного устарели, и я несколько отчаянно надеюсь, что что-то изменилось, поскольку ответы не могут быть выполнены.
Контекст:
class AbstractBuildObject {}
class Hammer extends AbstractBuildObject{}
class Nail extends AbstractBuildObject{}
class AbstractFactory{
/**
* return $type
*/
public function build1(string $type): AbstractBuiltObject {
return new $type();
}
/**
* return any(AbstractBuiltObject)
*/
public function build2(string $someArg): AbstractBuiltObject {
$type = $this->decideTypeBasedOnArgsAndState($someArg);
return new $type();
}
}
Я попытался представить то, что мне нужно, с помощью аннотаций над билдерами.
return $type
(или в идеале return $type of AbstractBuiltObject
должно намекать на то, что тип возвращаемого значения указан во входном параметре.
Во втором случае any(AbstractBuiltObject)
означает, что может быть возвращена любая производная конкретизация абстрактного класса.
Поэтому мне нужна какая-то аннотация для достижения описанных мной эффектов. Эти аннотации, очевидно, не работают, я просто использовал их для иллюстрации концепции.
Я знаю, что у кого-то может возникнуть соблазн использовать соединения типа конвейера, такие как return Hammer|Nail
, но в моем случае фабричный класс должен изменяться каждый раз, когда в проект добавляется новая конкретная реализация, он также недостаточно специфичен в случае build1
, где я точно знать, каким должен быть возвращаемый тип.
Короче говоря, мне нужно, чтобы это работало хотя бы в PhpStorm:
(new AbstractFactory())->build1(Hammer::class)-> // I should have Hammer autocomplete here
(new AbstractFactory())->build2('foo')-> // I should have autocomplete of any concretion of the abstract here
any(AbstractBuiltObject)
должен отличаться отAbstractBuiltObject
? Также обратите внимание, что то, что вы описываете, по сути, предназначено для интерфейсов. Сделайте так, чтобы ваши конкреции реализовали интерфейс, а затем введите интерфейс. - person Alex Howansky   schedule 04.03.2021any(AbstractBuiltObject)
должен быть эквивалентом статического анализатора жестко введенногоHammer|Nail
. То есть я должен получить автозаполнение и дальнейший тип iferrence для любого т.е. метода, который реализован наHammer
, но не на реферате. - person Dinu   schedule 04.03.2021