You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug]: @phpstan-type alias used in an @extends generic argument is read as a class name in parent methods #111
A subclass defines a type alias with @phpstan-type and uses it in the generic argument of its @extends tag. When a method declared in the parent returns the template, TypePHP checks the value against a class literally named after the alias instead of the alias's shape:
App\TotalsQuery::fetch(): Return value[0] must be of type Row, associative array (key 'user_id') returned
Row is array{user_id: int, total: float}, and the returned row matches it exactly. PHPStan (level 9) accepts the code.
Playground
Open in playground — output: run: App\TotalsQuery::fetch(): Return value[0] must be of type Row, associative array (key 'user_id') returned
run: App\TotalsQuery::fetch(): Return value[0] must be of type Row, associative array (key 'user_id') returned
Expected
run: OK
Control
Give the child's fetch() its own @return list<Row>: fetch() then passes, but run() (inherited, @return TOutput) still fails with the same message. So the alias resolves fine in the subclass's own docblocks, and is lost only when it travels through the template binding into a parent method. It looks like the type-alias counterpart of #93 (relative class name in a generic argument): the alias should be resolved in the scope of the class that wrote the @extends tag.
Versions
v0.11.3 and dev-main @ 4e4244e (local project, PHP 8.3, array_validation => 'full'), and the playground. PHPStan 2.3.0 level 9: no error.
Context
This is how our query commands type their results: the base class owns run()/manageQuery() returning TOutput, each concrete command declares its row shape as a local @phpstan-type and binds it in @extends. Every such command reports one violation per returned row.
Activity