larastan
larastan copied to clipboard
`Model::create()` issue with generics
- Larastan Version: 2.0.1
-
--level
used: 5 - Pull request with failing test:
Description
Not sure whether this is an issue with Larastan, Laravels type definitions or even PhpStan itself:
When running the Model::create()
function on a class-string with a template definition, that's causing an issue. Seems like PhpStan cannot figure out the correct type.
Method Domain\Document\Actions\Action::run() should return T of
Domain\Document\Models\Document but returns Domain\Document\Models\Document.
Laravel code where the issue was found
Simplified setup for the models:
abstract class Document extends Model {}
class Tour extends Document {}
class Analysis extends Document {}
Actual code which throws error
class Action
{
/**
* @template T of \Domain\Document\Models\Document
* @param class-string<T> $documentType
* @return T
*/
public function run(string $documentType): Document
{
return $documentType::create();
}
}
But this works:
class Action
{
/**
* @template T of \Domain\Document\Models\Document
* @param class-string<T> $documentType
* @return T
*/
public function run(string $documentType): Document
{
$document = new $documentType();
$document->save();
return $document;
}
}
Hi,
I tried to replicate this. And I think this can be an issue with PHPStan. I'll try to prepare an example and open an issue there.
Thanks.
Thank you!
Getting the same issue with Model::find()
/**
* @template T of Model
* @param class-string<T> $modelClassName
* @return T|null
*/
function findModel(string $modelClassName, int $id): ?Model
{
return $modelClassName::find($id);
}
Gives the PHPStan error:
Function findModel() should return (T of Illuminate\Database\Eloquent\Model)|null but returns Illuminate\Database\Eloquent\Model|null.
@canvural Did you ever make that issue in PHPStan?