DusanKasan / Knapsack

Collection pipeline library for PHP
http://dusankasan.github.io/Knapsack/
MIT License
535 stars 56 forks source link

Generify collections using Psalm #61

Open vv12131415 opened 4 years ago

vv12131415 commented 4 years ago

Since this collections lib is quite popular. I would like to suggest it to use generics/template types like doctrine/collections does. This will make it more type safe to use this collections

patrickkusebauch commented 4 years ago

I am working on this right now in the form of a Psalm plugin. The goal is to make it play nicely with both PHPStan and Psalm. The issue right now is that PHPStan wants it in the form of Collection<TValue>, however at the moment Psalm only recognizes Collection and Collection<TValue> will not pass.

The idea of the plugin is to make Psalm accept 2 forms: Collection<TValue> and Collection<Tkey, TValue>. If done correctly, once ported from the plugin into the new version docs even PHPStan should recognize both forms.

*TLDR; I am writing a Psalm plugin for this right now, so if you wait a day or two, it will be done. The plugin can be then ported into v 11..**

DusanKasan commented 4 years ago

Sounds great! :) Take a look at the changes done in the v11, we will be changing all the returned Collection instances into CollectionInterface. This is done so that when you use the provided trait in your own class, you will get back an instance of your class instead of our generic Collection. I was wondering how to describe this in the Psalm/PHPStan land but came empty so far :/

patrickkusebauch commented 4 years ago

This is from straight from Psalm documentation:

<?php
/**
 * @template T
 */
trait MyTrait {}

class Foo {
    /**
     * @use MyTrait<Foo>
     */
    use MyTrait;
}

I am not sure how well it works for PHPStan, but for Psalm, if client code for the use of the trait would look like this, they in the trait you have access to the client class name.

For anyone interested in helping, https://github.com/Dance-Engineer/psalm-knapsack-collections is the plugin. Since I am a templating newbie, I would appreciate any help. The plugin is installable and works, but some of the templates are wrong and cause errors even when they should not. PRs are welcomed. One sorted, it can be ported to this REPO and only exists for people using <v11.

vv12131415 commented 4 years ago

PHPStan wants it in the form of Collection, however at the moment Psalm only recognizes Collection and Collection will not pass

What if you will all phpstan or psalm specific tags, like

@psalm-var 
@phpstan-var
@var
DusanKasan commented 4 years ago

I implemented Psalm annotations for the collection functions, CollectionTrait, CollectionInterface and the Collection in https://github.com/DusanKasan/Knapsack/pull/63. There are still 10 "other issues" I can't really wrap my head around so any help is welcome :)

It's stuff like:

INFO: InvalidArgument - src/CollectionTrait.php:33:29 - Type TVal:DusanKasan\Knapsack\CollectionTrait as mixed should be a subtype of TVal:DusanKasan\Knapsack\Collection as mixed (see https://psalm.dev/004)
        return static::from(filter($this->getItems(), $function));