Fabio Sasso
Fabio Sasso

Reputation: 185

Larastan complains about collection methods paramaters after upgrading to Laravel 10

After upgrading to Laravel 10 I'm having hard times with Larastan errors.

The following code which was perfectly fine until 1 hour ago:

return $this->articleRepository->getDefaultArticles($organizationId)
    ->toBase()
    ->map(function (Article $article) {
        return new Content(
            $article->id,
            $article->title,
            $article->language,
        );
    })
    ->toArray();

now gives me the following error:

Parameter #1 $callback of method Illuminate\Support\Collection<(int|string),Illuminate\Database\Eloquent\Model>::map() expects callable(Illuminate\Database\Eloquent\Model, int|string): App\Academy\Content,
Closure(App\Models\Article): App\Academy\Content given

The repository method has the correct hint:

/**
 * @return Collection<Article>
 */
public function getDefaultArticles(OrganizationId $organizationId): Collection
{
    /** @var Collection<Article> */
    return Article::query()
        ->where('organization_id', $organizationId)
        ->get()
        ->keyBy('id')
        ->values();
}

It gives me 115 new errors and most of them are similar to this, related to collection methods like map and reduce.

The quick solution would be using a temporary variable and add a type hinting:

/** @var Collection<Article> $articles */
$articles = $this->articleRepository
    ->getDefaultArticles($organizationId)
    ->toBase();

but I don't want to do it 100 times and even the IDE is complaining that's unnecessary

enter image description here

Thanks in advance for you help!

Upvotes: 6

Views: 3501

Answers (5)

HichemTech
HichemTech

Reputation: 519

Try removing the Article type from the callback of map :

...
->map(function ($article) {
        return new Content(
            $article->id,
            $article->title,
            $article->language,
        );
    })
...

Upvotes: -1

Oliver Hader
Oliver Hader

Reputation: 4202

Static code analysis tools have the possibility to create a baseline file, which contains existing and known errors to be fixed later - either fixed in the code, or with a corresponding update of the parser & inference tools. This baseline is for instance supported in PhpStan/LaraStan or PsalmPHP.

This way you can acknowledge the described inference flaws and continue with focussing again on the actual application logic.

Baseline file

In older codebases it might be hard to spend the time fixing all the code to pass a high PHPStan Level.

To get around this a baseline file can be generated. The baseline file will create a configuration file with all of the current errors, so new code can be written following a higher standard than the old code. (PHPStan Docs)

vendor/bin/phpstan analyse --generate-baseline

source: https://github.com/nunomaduro/larastan#baseline-file

Find more details in PhpStan's The Baseline section.

Upvotes: -1

Christian
Christian

Reputation: 436

try

/**
* @return Collection<int,Article>
*/

for getDefaultArticles php doc type

see this: https://github.com/nunomaduro/larastan/blob/master/UPGRADE.md#eloquent-collection-now-requires-2-generic-types

Upvotes: 1

Yevgeniy Afanasyev
Yevgeniy Afanasyev

Reputation: 41360

the solution that worked for me was downgrading phpstan:

$ composer require phpstan/phpstan:1.10.11 --dev

Upvotes: 0

Yevgeniy Afanasyev
Yevgeniy Afanasyev

Reputation: 41360

The only work around I found so far is to make it in 2 steps with type hinting.

/** @var \Illuminate\Support\Collection $result */
$result = $this->articleRepository->getDefaultArticles($organizationId);

return $result->map(function (Article $article) {
    return new Content(
        $article->id,
        $article->title,
        $article->language,
    );
})
->toArray();

it does not really help to deal with 115 new errors. But if you would have couple errors, it would help.

Upvotes: 1

Related Questions