Context
The context: you have a Laravel 10/11/12 project, and you want to use PHPStan.
You use a PHPStan level 6 (or higher), because it's cool! (and you're right about that).
You execute the PHPStan command, and this is one of the error you get:
------ -----------------------------------------------------------------------------------------------------------------------------
Line Models\Base\Comment.php
------ -----------------------------------------------------------------------------------------------------------------------------
82 Method App\Models\Base\Comment::commentable() return type with generic class Illuminate\Database\Eloquent\Relations\MorphTo
does not specify its types: TRelatedModel, TDeclaringModel
🪪 missingType.generics
------ -----------------------------------------------------------------------------------------------------------------------------
What happened?
You have a model defined like this:
public function commentable(): MorphTo
{
return $this->morphTo(__FUNCTION__, 'commentable_type', 'commentable_id');
}
Without PHPDoc, PHPStan is unable to check your code to verify if everything is correct.
How can you fix this?
Add this PHPDoc to the function:
/**
* @return MorphTo<Model, $this>
*/
public function commentable(): MorphTo
{
return $this->morphTo(__FUNCTION__, 'commentable_type', 'commentable_id');
}
Following are all PHPDocs you need to add to Laravel relationships to pass PHPStan level > 6 check.
Laravel Relationships
HasOne
/**
* @return HasOne<PostFollowingPost, $this>
*/
public function postFollowingPostsAsFollowing(): HasOne
{
return $this->hasOne(PostFollowingPost::class, 'following_id', 'id');
}
BelongsTo
/**
* @return BelongsTo<Post, $this>
*/
public function post(): BelongsTo
{
return $this->belongsTo(Post::class, 'id_post');
}
HasMany
/**
* @return HasMany<PostFollowingPost, $this>
*/
public function postFollowingPostsAsFollowing(): HasMany
{
return $this->hasMany(PostFollowingPost::class, 'following_id', 'id');
}
HasOneThrough
/**
* @return HasOneThrough<Post, Pivot, $this>
*/
public function posts(): HasOneThrough
{
return $this->hasOneThrough(Post::class, Pivot::class, 'post_id', 'id');
}
HasManyThrough
/**
* @return HasManyThrough<Post, Pivot, $this>
*/
public function posts(): HasManyThrough
{
return $this->hasManyThrough(Post::class, Pivot::class, 'post_id', 'id');
}
BelongsToMany
/**
* @return BelongsToMany<Post, $this>
*/
public function posts(): BelongsToMany
{
return $this->belongsToMany(Post::class, 'post_id', 'id');
}
MorphTo
/**
* @return MorphTo<Model, $this>
*/
public function commentable(): MorphTo
{
return $this->morphTo(__FUNCTION__, 'commentable_type', 'commentable_id');
}
MorphOne
/**
* @return MorphOne<Post, $this>
*/
public function post(): MorphOne
{
return $this->morphOne(Post::class, 'postable');
}
MorphMany
/**
* @return MorphMany<Post, $this>
*/
public function posts(): MorphMany
{
return $this->morphMany(Post::class, 'postable');
}
MorphToMany
/**
* @return MorphToMany<Post, $this>
*/
public function posts(): MorphToMany
{
return $this->morphToMany(Post::class, 'name');
}
I developed a package to generate Laravel Models from an existing database.
The package generates code PHPStan level max compliant:
https://github.com/giacomomasseron/laravel-models-generator
Top comments (0)