Open11
https://github.com/larastan/larastan/issues/1149
これに取り組んでみる
再現してみる
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();
}
}
このコードから推測するに、モデルは app/Domain/Document/Models/ におく?
ちがう。トップレベルがDomainだから、オートロード設定で、Domainに紐づくディレクトリを決めてやらないといけない。
"autoload": {
"psr-4": {
"App\\": "app/",
+ "Domain\\": "domain/",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/"
}
},
これで、dumo-autoloadを打つ
dump-autoload打った
Generated optimized autoload files containing 6246 classes
とりあえず、Domain\Document\Modelsの名前空間のところにAction作ってphpstanかけてみる
Domain/Document/Models/Action.php
<?php
namespace Domain\Document\Models;
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();
}
/**
* @template T of \Domain\Document\Models\Document
* @param class-string<T> $documentType
* @return T
*/
public function run2(string $documentType): Document
{
$document = new $documentType();
$document->save();
return $document;
}
}
run1のところでエラーが出る。
おそらく再現した
$ ./vendor/bin/phpstan analyse Domain/Document/Models/Action.php
Note: Using configuration file /Users/akinori/development/example-app/phpstan.neon.
1/1 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
------ ---------------------------------------------------------------------------------------------------------------------------------------------
Line Action.php
------ ---------------------------------------------------------------------------------------------------------------------------------------------
:14 Method Domain\Document\Models\Action::run() should return T of Domain\Document\Models\Document but returns Domain\Document\Models\Document.
💡 Type Domain\Document\Models\Document is not always the same as T. It breaks the contract for some argument types, typically subtypes.
------ ---------------------------------------------------------------------------------------------------------------------------------------------
[ERROR] Found 1 error
class-stringを引数に渡して、動的にレコードを生成する関数か
ジェネリクスあまりわかってないので、改めて調べてみる
これ読む
@template T of \Domain\Document\Models\Document
なので、ここらへんが関係ありそう
phpstan側の問題かもとの指摘