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]: Relative class name inside an array shape in a generic argument is not resolved #93
In @extends Box<array{user: User}>, User is not resolved against the current namespace, so the right object is rejected.
<?phpnamespaceApp;
class User {}
/** @template T */class Box
{
/** @param T $value */publicfunctionput(mixed$value): void {}
}
/** @extends Box<array{user: User}> */class UserBox extends Box {}
(newUserBox())->put(['user' => newUser()]);
Fatal error: Uncaught TypePHP\Exception\TypeError: App\UserBox::put(): Argument $value (template T = array{user: User})['user'] must be of type User, App\User given in playground.php on line 17
What passes and what fails:
Docblock
Result
@param array{user: User} $v (no generics)
OK
@extends Box<User>
OK
@extends Box<list<User>>
OK
@extends Box<array{user: \App\User}>
OK
@extends Box<array{user: User}>
fails
Same with an imported class (use Models\User;): must be of type User, Models\User given.
Tested on v0.10.26 and on main (2ec0426).
No error: User inside the shape is App\User, as it is everywhere else in the file and as PHPStan resolves it.
Context: in our codebase almost every command declares its options as @extends Command<array{module: SiModule, agency: Agency, ...}>, so this stops our test suite at bootstrap. Thanks for TypePHP, it already caught three wrong docblocks in our core that PHPStan missed.
This issue has now been resolved//
Under the hood, I have added recursive FQCN namespace resolution across all inherited generic tags (@extends, @implements, and @use on traits). Beyond array shapes, this fix also comprehensively covers unqualified class names inside:
Activity
rcalicdan commentedon Oct 3, 2026
Thank you for this bug report, this will be fix in next patch release..
rcalicdan commentedon Oct 3, 2026
Hi
This issue has now been resolved//
Under the hood, I have added recursive FQCN namespace resolution across all inherited generic tags (@extends, @implements, and @use on traits). Beyond array shapes, this fix also comprehensively covers unqualified class names inside:
Array & Object shapes (e.g. array{user: User}, object{user: User})
Callables & Closures (e.g. callable(User): User)
Iterables & Generators (e.g. iterable, Traversable<string, User>, Generator<int, User>)
A full regression test suite covering classes, interfaces, and traits has been added, and the fix will be included in the v0.10.28 patch released..