Skip to content

support for generic params on alias types#297

Open
shmax wants to merge 3 commits intophpstan:2.3.xfrom
shmax:generics-on-phpstan-types
Open

support for generic params on alias types#297
shmax wants to merge 3 commits intophpstan:2.3.xfrom
shmax:generics-on-phpstan-types

Conversation

@shmax
Copy link
Copy Markdown
Contributor

@shmax shmax commented Apr 2, 2026

Add Generic Type Parameters to Type Aliases

This PR adds support for generic type parameters on @phpstan-type aliases, including multiline syntax support.

See: phpstan/phpstan-src#5378

Features

Generic Type Parameters on Type Aliases

Type aliases can now declare template parameters directly on the alias definition:

/**
 * @phpstan-type Wrapper<T> T
 * @phpstan-type Pair<TFirst, TSecond> array{first: TFirst, second: TSecond}
 * @phpstan-type Collection<T of object> list<T>
 * @phpstan-type WithDefault<T = string> T
 */

Multiline Syntax Support

Complex generic type aliases can be formatted across multiple lines for improved readability:

/**
 * @phpstan-type Response<
 *     TData,
 *     TError extends \Throwable
 * > array{
 *     success: bool,
 *     data: TData|null,
 *     error: TError|null
 * }
 */

/**
 * @phpstan-type Repository<
 *     TEntity of object,
 *     TKey of int|string
 * > interface {
 *     find(TKey): ?TEntity,
 *     save(TEntity): void
 * }
 */

Use Cases

This enables more flexible and reusable type definitions:

/**
 * @phpstan-type Result<T, E = \Exception> array{ok: bool, value: T|null, error: E|null}
 */
class ResultHandler
{
    /**
     * @param Result<User, AuthException> $result
     */
    public function handle(array $result): void
    {
        // ...
    }
}

Technical Details

AST Changes

  • TypeAliasTagValueNode now includes a $templateTypes property containing an array of TemplateTagValueNode[]
  • The parser recognizes <...> syntax immediately after the alias name
  • Supports all template features: bounds (of), defaults (=), and multiple parameters

Parser Behavior

The parser now:

  • Skips horizontal whitespace and PHPDoc line continuations inside <...>
  • Parses each template parameter using the existing parseTemplateTagValue() method
  • Maintains backward compatibility with non-generic type aliases

Printer Support

The Printer class correctly outputs generic type aliases with template parameters in both regular and format-preserving modes.

Testing

Added comprehensive test coverage:

  • Single template parameter
  • Multiple template parameters
  • Bounded template parameters (T of object)
  • Default template parameters (T = string)
  • Multiline formatting with whitespace
  • Integration with existing type alias features

All existing tests pass, ensuring backward compatibility.

Examples

Before (workaround)

/**
 * @template T
 * @phpstan-type Container array{value: T}
 */

After (direct declaration)

/**
 * @phpstan-type Container<T> array{value: T}
 */

This aligns PHPDoc type alias syntax more closely with TypeScript, Java, and other languages that support generic type declarations.

@shmax shmax marked this pull request as draft April 2, 2026 15:57
@shmax shmax marked this pull request as draft April 2, 2026 15:57
@shmax shmax marked this pull request as ready for review April 2, 2026 16:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant