mtorromeo / phpstan-yield
PHPStan extension to support @yield
Requires
- phpstan/phpstan: ^2.1
Requires (Dev)
- carthage-software/mago: ^1.15
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-phpunit: ^2.0
- phpunit/phpunit: ^13.0
README
A PHPStan extension that enables type inference for yield expressions using @yield annotations on classes.
Purpose
PHP generators use yield to suspend execution and return values to the caller. However, PHPStan has no built-in way to know what type a yield expression resolves to on the call side — i.e., the value sent back into the generator via Generator::send() or resolved by an async framework.
This extension solves that by reading @phpstan-yield, @psalm-yield, or @yield annotations from the docblock of the class being yielded. When PHPStan encounters yield $value, it looks up the type annotation on the class of $value (and its entire class hierarchy) to infer what the yield expression returns.
This is particularly useful for coroutine-based async frameworks where yielding a promise-like object causes the scheduler to suspend the coroutine and eventually resume it with the resolved value.
Example
use React\Promise\PromiseInterface; /** * @return PromiseInterface<User> */ function fetchUser(int $id): PromiseInterface { // ... } $user = yield fetchUser($id); // PHPStan now knows $user is of type User echo $user->name;
Without this extension, PHPStan would infer $user as mixed. With it, the type is correctly resolved from the @yield T annotation in PromiseInterface combined with the generic argument User.
Requirements
- PHP 8.1+
- PHPStan ^2.1
Installation
To use this extension require it in composer:
composer require --dev mtorromeo/phpstan-yield
The extension registers itself automatically if you have installed phpstan/extension-installer. Otherwise, include the extension manually in your project's PHPStan configuration:
includes: - vendor/mtorromeo/phpstan-yield/extension.neon
Annotations
The extension recognizes three equivalent annotation tags on class docblocks:
| Tag | Description |
|---|---|
@phpstan-yield <type> |
PHPStan-specific (recommended) |
@psalm-yield <type> |
Psalm-compatible alias |
@yield <type> |
Generic alias |
The type can be any valid PHPStan type expression, including:
- Concrete types:
@phpstan-yield string,@phpstan-yield User - Template types:
@phpstan-yield T(resolved against generic arguments) - Complex types:
@phpstan-yield array<string, int>
How It Works
When PHPStan analyses a yield $value expression, the extension:
- Determines the type of
$value - Traverses the full class hierarchy of that type (parent classes and all interfaces) using breadth-first search
- Looks for a
@phpstan-yield,@psalm-yield, or@yieldtag in the docblock of each class/interface - Resolves the annotated type in the context of the declaring class (handling namespace imports correctly)
- If the annotation uses a template type (e.g.
@phpstan-yield T), binds it against the actual generic arguments of$value
The search stops at the first class or interface in the hierarchy that provides a yield annotation. Annotations on parent classes and interfaces are inherited, so you only need to annotate the base class or interface.
Development
# Run tests composer test # Run static analysis composer phpstan # Format code composer format
License
MIT — see LICENSE for details.