Repository navigation
[Bug]: Property @var is not resolved when the property is declared in a trait used by another trait #103
Description
Bug report
When a property is declared in a trait, and that trait is used by another trait (not directly by the class), the class names in the property's @var are not resolved against the declaring trait's use imports. Every assignment of a correct object is then rejected. The @param of a method in the same trait resolves fine.
The error shows the short name (Entity), while a working check prints the fully qualified one (App\Contracts\Entity), so the name seems to be left unresolved.
Five files plus composer.json, default config (no typephp.php):
composer.json
{"require": {"typephp/typephp": "0.10.26"}, "autoload": {"psr-4": {"App\\": "src/"}}}src/Contracts/Entity.php
<?php
namespace App\Contracts;
interface Entity
{
}src/Traits/GroupTrait.php (declares the property, imports Entity)
<?php
namespace App\Traits;
use App\Contracts\Entity;
trait GroupTrait
{
/** @var list<Entity>|null */
private ?array $group = null;
/** @param list<Entity> $entities */
public function setGroup(array $entities): void
{
$this->group = $entities;
}
}src/Traits/OuterTrait.php
<?php
namespace App\Traits;
trait OuterTrait
{
use GroupTrait;
}src/Model/Agency.php
<?php
namespace App\Model;
use App\Contracts\Entity;
use App\Traits\OuterTrait;
final class Agency implements Entity
{
use OuterTrait;
}run.php
<?php
require __DIR__ . "/vendor/autoload.php";
$agency = new App\Model\Agency();
$agency->setGroup([$agency]);
echo "OK\n";Result:
PHP Fatal error: Uncaught TypePHP\Exception\TypeError: Property App\Model\Agency::$group[0] must be of type Entity, App\Model\Agency given
| Variant | Result |
|---|---|
@var list<Entity>|null, trait used through OuterTrait |
TypeError |
@var ?Entity / @var Entity|null (no array), same nesting |
TypeError |
@var list<Entity1&Entity2>|null (intersection), same nesting |
TypeError, message prints (Entity1 & Entity2) |
Same files, Agency uses GroupTrait directly |
OK |
$agency->setGroup(['x']) (argument check, same nesting) |
correctly rejected, message prints App\Contracts\Entity |
TYPEPHP_DISABLE=1 |
OK |
Tested on v0.10.26 (2ec0426), main (88fcb12) and next-minor-released (08baad4, PR #100), PHP 8.3, type cache cleared before each run.
Code snippet that reproduces the problem
No playground link: the bug needs the trait and the class in separate files with their own namespaces and imports, which a single-file playground cannot express. The files above are complete.
Expected output
OK
Context: same codebase as #93 / #99 / #101 / #102. This looks like a variant #99's fix does not cover (#99 is a trait assigning a parent's property; here the property is declared in a nested trait). We validated PR #100 against our test suites with property checks on: this one stops PHPUnit at bootstrap for two of our modules, because the metadata trait of every entity is used through another trait.
Activity
rcalicdan commentedon Oct 4, 2026
Nice find, I'm pretty sure my previous fix is not recursively checking trait metadata. that was on me.., I will do fix on it..
rcalicdan commentedon Oct 4, 2026
Hello should be fix now on the latest commit 925957a in #100