calebdw / larastan

⚗️ Adds code analysis to Laravel improving developer productivity and code quality.
MIT License
4 stars 0 forks source link

MorphTo relation #9

Closed rcerljenko closed 3 months ago

rcerljenko commented 3 months ago

Description

Hi,

First of all many thanks for your efforts and this fork! I have a question regarding eloquent relations feture that you've added in this fork. Everything works great but I can't seem to make phpstan work with MorphTo relation.

This is the issue that I'm getting:

Method App\Models\Notification::parent() should return Illuminate\Database\Eloquent\Relations\MorphTo<App\Contracts\HasNotifications&App\Models\Model, $this(App\Models\Notification)> but returns Illuminate\Database\Eloquent\Relations\MorphTo<Illuminate\Database\Eloquent\Model, $this(App\Models\Notification)>.

Laravel code where the issue was found

/**
 * @return MorphTo<HasNotifications&Model, $this>
 */
public function parent(): MorphTo
{
    return $this->morphTo();
}

HasNotifications - a contract Model - custom model class which extends Laravel Eloquent Model

calebdw commented 3 months ago

@rcerljenko,

Thanks for reporting! However, this error is correct---there is no way for static analysis to determine what models can actually be returned, so the ->morphTo() method always returns MorphTo<Illuminate\...\Model, $this> (notice that this method does not accept a class string like other relation methods).

Your options are:

  1. you can ignore the error and phpstan should use the intersection type that you've defined when outside this method. However, this can be brittle as there's nothing enforcing that HasNotifications&Model is returned from the relation---you could potentially have an IlluminateModel returned which could break your code.
  2. you can correct the generic and everywhere you use the relation you will either need to use the public model api (->getKey(), ->getAttribute() instead of property access, etc.) or you will need to narrow the type assert($model instanceof HasNotifications)
calebdw commented 3 months ago

Let me know if you have any questions or need help with specific examples!