Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setter for collection type #61

Open
gnumoksha opened this issue Aug 30, 2018 · 2 comments
Open

Setter for collection type #61

gnumoksha opened this issue Aug 30, 2018 · 2 comments

Comments

@gnumoksha
Copy link

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.

@danielgsims
Copy link
Owner

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])?

@gnumoksha
Copy link
Author

@danielgsims the first option :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants