php-collections
php-collections copied to clipboard
Setter for collection type
At work we use this collections to improve type hinting. Example:
use \Foo\Bar\UrlCollection;
class SomeClass
{
/** @var \Foo\Bar\UrlCollection */
private $urls;
public function __construct(UrlCollection $urls)
{
$this->urls = $urls;
}
public function getUrls() : UrlCollection
{
return $this->urls;
}
}
$config = new SomeClass(new UrlCollection(Url::class, $items));
But we always need to declare the collection type, which is strange because we have a class for the collection and it should know his type.
As result we ended up with this abstract class:
declare(strict_types=1);
namespace Foo\Bar;
use Collections\Collection;
abstract class SmartTypeCollection extends Collection
{
/**
* Creates a new collection with only $typeOrItems parameter.
* @param string|mixed[] $typeOrItems you will pass only this parameter that contains you data in an array.
* @param mixed[] $items this parameter will be passed only by Collection class.
* @throws \Collections\Exceptions\InvalidArgumentException
*/
public function __construct($typeOrItems, ?array $items = [])
{
if (\is_string($typeOrItems)) {
$type = $typeOrItems;
} else {
$type = $this->getSmartType();
}
if (\is_array($typeOrItems)) {
$items = $typeOrItems;
}
parent::__construct($type, $items);
}
/**
* This method will return a string specifying the type for the collection's items.
*/
abstract protected function getSmartType() : string;
}
Wich allow us to do this:
namespace \Foo\Bar;
class UrlCollection extends SmartTypeCollection
{
/** {@inheritdoc} */
protected function getSmartType() : string
{
return \Foo\Bar\Url::class;
}
}
$config = new SomeClass(new UrlCollection($items));
I'm wondering if it makes sense to you, and if so, there is a way to add this feature into this project.
Are you looking to be able to create more specific classes of the collection so you can type hint on specific types?
Example: UrlCollection extends Collection
Or are you just looking for type inference on type of items the collection uses at construction?
Example: new Collection([new Url])
?
@danielgsims the first option :)