php-collections icon indicating copy to clipboard operation
php-collections copied to clipboard

Setter for collection type

Open gnumoksha opened this issue 6 years ago • 2 comments

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.

gnumoksha avatar Aug 30 '18 12:08 gnumoksha

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 avatar Aug 30 '18 13:08 danielgsims

@danielgsims the first option :)

gnumoksha avatar Aug 30 '18 13:08 gnumoksha