Skip to content

Commit d92708f

Browse files
committed
Support various forms of type narrowing
1 parent d22bbc4 commit d92708f

3 files changed

Lines changed: 2056 additions & 20 deletions

File tree

example.php

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,11 @@ public function bind(string $abstract, object $obj): void
380380
{
381381
$this->bindings[$abstract] = $obj;
382382
}
383+
384+
public function getStatus(): int
385+
{
386+
return 404;
387+
}
383388
}
384389

385390
// ─── Standalone Functions ───────────────────────────────────────────────────
@@ -478,15 +483,28 @@ function getUnknownValue()
478483

479484
// Union types — ambiguous variable across conditional branches
480485
if (rand(0, 1)) {
481-
$ambiguous = new User('X', 'x@example.com');
486+
$ambiguous = new Container();
482487
} else {
483488
$ambiguous = new AdminUser('Y', 'y@example.com');
484489
}
485-
$ambiguous->getName(); // Both User and AdminUser have getName()
490+
$ambiguous->getStatus(); // Both Container and AdminUser have getStatus()
491+
if ($ambiguous instanceof AdminUser) {
492+
$ambiguous->addRoles('reviewer');
493+
} else {
494+
$ambiguous->bind($ambiguous::class, $ambiguous);
495+
}
486496

487497
// Union return type resolution
488498
$found = findOrFail(1);
489499
$found->getName(); // User|AdminUser — union completion
500+
if ($found instanceof User) {
501+
$found->addRoles('triage'); // AdminUser extends User
502+
}
503+
504+
// Narrow using assert()
505+
$asserted = getUnknownValue(1);
506+
assert($asserted instanceof User);
507+
$asserted->addRoles();
490508

491509
// Go-to-definition targets:
492510
// - Hover over `User` to jump to its class definition

0 commit comments

Comments
 (0)