You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级Laravel 10后Larastan集合方法参数报错问题

Laravel 10升级后Larastan集合方法批量报错解决方案

升级Laravel 10后,出现大量Larastan报错,集中在map、reduce等集合方法的类型不匹配上。

问题示例

原正常运行的代码:

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

抛出错误:

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

仓库方法已添加正确的类型提示:

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

临时解决方案是用带类型提示的临时变量,但需要重复上百次,且IDE提示该操作无必要:

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

高效解决方案

1. 更新Larastan到最新版本

Laravel 10的兼容性问题可能已被修复,执行更新:

composer update nunomaduro/larastan

更新后重新运行Larastan分析,看报错是否消除。

2. 修复toBase()的类型推断偏差

Larastan对toBase()的泛型类型继承存在问题,可通过配置扩展修正:
在项目的phpstan.neon中添加:

services:
    -
        class: PHPStan\Type\Laravel\Eloquent\CollectionToBaseExtension
        tags:
            - phpstan.broker.methodTypeExtension

如果默认没有该扩展,可自定义一个简单的类型扩展,让toBase()返回与原集合相同泛型参数的基础Collection。

3. 全局配置增强集合类型推断

在phpstan.neon中配置Larastan的模型集合扩展,确保链式调用时泛型类型不丢失:

parameters:
    larastan:
        modelExtensions:
            - App\Extensions\CustomModelCollectionExtension

自定义CustomModelCollectionExtension来优化集合方法链式调用的类型推断逻辑。

4. 批量添加内联类型提示(无需临时变量)

用IDE的全局替换功能,在链式调用的起始处添加内联类型注释,替代临时变量:

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

这种方式比临时变量更简洁,且能批量处理所有报错。

内容的提问来源于stack exchange,提问作者Fabio Sasso

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 16:17:04