| 596 | class ClosureParamTemplateDemo |
| 597 | { |
| 598 | public function demo(): void |
| 599 | { |
| 600 | // When a method declares @param Closure(T): void $cb, the template |
| 601 | // param T is inferred from the closure's *parameter* type annotation |
| 602 | // (contravariant position), not the return type. |
| 603 | |
| 604 | $bus = new ScaffoldingEventBus(); |
| 605 | |
| 606 | // Arrow function: T inferred as Pen from fn(Pen $p) |
| 607 | $result = $bus->listen(function(Pen $p): void { $p->write(); }); |
| 608 | $result->write(); // T = Pen |
| 609 | $result->color(); // completions for Pen |
| 610 | |
| 611 | // Full closure: T inferred as User from function(User $u) |
| 612 | $user = $bus->listen(function(User $u): void { $u->getEmail(); }); |
| 613 | $user->getName(); // T = User |
| 614 | |
| 615 | // Second param position: @param Closure(int, T): void |
| 616 | $proc = new ScaffoldingBatchProcessor(); |
| 617 | $item = $proc->process(function(int $i, Pencil $p): void { $p->sketch(); }); |
| 618 | $item->sketch(); // T = Pencil (from position 1) |
| 619 | $item->sharpen(); |
| 620 | } |
| 621 | } |
| 622 | |
| 623 | |