/**
* @template T
*/
abstract class Factory
{
/**
* @return T
*/
public static function createOne(): mixed
{
return static::new()->create();
}
public static function new(): static
{
return new static(); // @phpstan-ignore-line
}
/**
* @return T
*/
abstract public function create(): mixed;
}
/**
* @template T of object
* @extends Factory<T>
*/
abstract class ObjectFactory extends Factory
{
public function create(): object
{
return new \stdClass(); // @phpstan-ignore-line
}
/**
* @return class-string<T>
*/
abstract public static function class(): string;
}
/**
* @template T of object
* @extends ObjectFactory<T>
*/
abstract class PersistentObjectFactory extends ObjectFactory
{
public function create(): object
{
return parent::create();
}
}
/**
* @template T of object
*/
interface Proxy
{
/**
* @return T
*/
public function unwrap(): object;
}
/**
* @template T of object
* @extends PersistentObjectFactory<T&Proxy<T>>
*
* @method static class-string<T> class()
*/
abstract class ProxyObjectFactory extends PersistentObjectFactory
{
/**
* @return class-string<T>
*/
abstract public static function class(): string;
}
class User
{
public string $name;
}
/**
* @extends ProxyObjectFactory<User>
*/
class UserFactory extends ProxyObjectFactory
{
public static function class(): string
{
return User::class;
}
}
I'm thinking the following inheritance structure:
I know this works with phpstan (https://phpstan.org/r/056810e5-6867-491e-9c8a-8afd994db84f) but can't get phpstan to pass locally...