larastan / larastan

⚗️ Adds code analysis to Laravel improving developer productivity and code quality.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

@var tag specifies the type already inferred from source code

hmingv opened this issue · comments

  • Larastan Version: 2.6.4
  • --level used: 9

Description

When I call the get() method of the Illuminate\Database\Eloquent\Relations class, I need to specify a generic type for the variable assigned to it, otherwise, if I call the map() method, phpstan will prompt me with the following error:
image

But when I specify a generic type for it, the PHPStorm editor will tell me that it has guessed the type and let me delete @var.

When I went to look at the annotations of the get() method, I found that it didn't use @template to define the generic type, which caused this problem.
image

I don't know if this is a Laravel problem or if this problem should be solved by Larastan, so I want to ask for some help here.

Thank you so much.

Laravel code where the issue was found

    public function unreadAll(): JsonResponse
    {
        /** @var Admin $admin */
        $admin         = $this->auth->user();
        /** @var Collection<int, NotificationMessageModel> $notifications */
        $notifications = $admin->unreadNotifications()->get();
        $notifications = $notifications->map(fn (NotificationMessageModel $message) => $this->format($message, false));

        return $this->success(__('Successfully'), compact('notifications'));
    }
    /**
     * Get the entity's notifications.
     *
     * @return MorphMany
     */
    public function notifications(): MorphMany
    {
        return $this->morphMany(NotificationMessage::class, 'notifiable')->latest();
    }

    /**
     * Get the entity's unread notifications.
     *
     * @return MorphMany
     */
    public function unreadNotifications(): MorphMany
    {
        return $this->notifications()->unread();
    }

Adding the related model may help.

    /**
     * Get the entity's unread notifications.
     *
     * @return MorphMany<NotificationMessage>
     */
    public function unreadNotifications(): MorphMany

Thanks for your reply, but the above method didn't help me, phpstan still says I have the same problem.

/** @var Collection<int, NotificationMessageModel> $notifications */
$notifications = $admin->unreadNotifications()->get();

The above code is valid, but the editor is not friendly
image

@var tag specifies the type already inferred from source code

Do you think the above statement is untrue?

This is the hint given by my editor. It did detect that the return value is a Collection class, but it did not correctly detect that the item in it is a NotificationMessage.

I don't think it's quite right.

Then I tried the following code:

image

But this time, my editor didn't make any suggestions. The difference between these two pieces of code is that one is an relation query and the other is an ordinary model query.

I'm using PHPStorm.

I see! So the problem is that PHPStorm needs a hint but Larastan does not.
I do not know how to help you.

... maybe adding Larastan's stubs to PHPStorm???
https://www.jetbrains.com/help/phpstorm/php.html#php-runtime-tab

I created a demo for this

https://github.com/hmingv/demo-for-phpstan

you need to execute

composer install

./vendor/bin/phpstan

You can see the error message.

Also, a pleasant surprise, I tested the same code with Laravel 10.x without any problems.

Adding the related model may help.

    /**
     * Get the entity's unread notifications.
     *
     * @return MorphMany<NotificationMessage>
     */
    public function unreadNotifications(): MorphMany

This works in Laravel 10.x.

Sorry, forgot to mention, I'm using Laravel 9.x

... maybe adding Larastan's stubs to PHPStorm???

Since I found Laravel 10.x to be fine, I figured it shouldn't be about PHPStorm.

Closing as it seems it is not related to Larastan itself.