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

Builder doesn't have correct generic when initialized through class-string #2021

Closed
vixducis opened this issue Aug 14, 2024 · 2 comments
Closed
Labels
enhancement New feature or request

Comments

@vixducis
Copy link

  • Larastan Version: 2.9.2
  • Laravel Version: 11.1.1

Description

When you initialize a Builder through the ::query() method on a class-string, the generic on the Builder isn't correctly deduced from the generic of the class-string, and defaults to Model. This can be easily tested by trying to access a local scope on the query, as demonstrated by the code below. This results in a PHPStan error: Call to an undefined method Illuminate\Database\Eloquent\Builder::test()..

It's debatable whether this is a bug or rather a feature request.

Laravel code where the issue was found

<?php

namespace App\Models\Example;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;

class Example extends Model
{
    public function scopeTest(Builder $query): void {}
}

/** @var class-string<Example> $className */
$className = Example::class;
$className::query()
    ->test()
    ->get();
@vixducis vixducis added the bug Something isn't working label Aug 14, 2024
@szepeviktor szepeviktor added enhancement New feature or request and removed bug Something isn't working labels Aug 14, 2024
@calebdw
Copy link
Contributor

calebdw commented Aug 14, 2024

👍 I'll try to get to this in the next week or two

A similar issue I've noticed is calling static::query() does not handle the static instance:

class AbstractModel extends Model
{
    public static function new(): static
    {
        return static::query()->create(); // fails, returns AbstractModel instead of static(AbstractModel)
    }
}

class User extends AbstractModel {}

\PHPStan\Testing\assertType('User', User::new());

@JeRabix
Copy link
Contributor

JeRabix commented Aug 25, 2024

I try help for first part of this issue, but currently can't understand how fix this:

 return static::query()->create(); // fails, returns AbstractModel instead of static(AbstractModel)

ModelDynamicStaticMethodReturnTypeExtension- skip all native class methods except only this:

if (in_array($name, ['get', 'hydrate', 'fromQuery'], true)) {
   return true;
}

when add method new to this except rule - it work correctly.

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

No branches or pull requests

5 participants