PHP TypeLang Help

@template

The @template tag declares a generic type parameter on a class, interface, trait, function, or method — a name such as T that can then be referenced by other tags on the same element, most notably @param and @return, or by a subclass through @extends and @implements. Without a @template declaration first introducing T, those tags would have no way to know that T names a type variable rather than an unresolved class reference.

"@template" <Name> [ "of" <Type> ] [ "=" <Type> ] [ <Description> ]

The optional "of" clause constrains what the parameter is allowed to be — an upper bound — and the optional "=" clause supplies a default type to use when a use site omits the parameter entirely.

Parsing a @template tag produces a TemplateTag instance exposing:

  • $parameter — the declared name, such as T.

  • $bound — the TypeReference after "of", or null if there is none.

  • $default — the TypeReference after "=", or null if there is none.

abstract class TypeParameterTag extends Tag { public function __construct( string $name, public readonly string $parameter, public readonly ?TypeReference $bound = null, public readonly ?TypeReference $default = null, ?DescriptionInterface $description = null, ) { parent::__construct($name, $description); } } final class TemplateTag extends TypeParameterTag {}

A plain @template is invariant: analyzers treat Collection<T> as unrelated to Collection<U> even when T and U are themselves related. @template-covariant and @template-contravariant relax that in opposite directions for parameters used only in output or only in input positions. This component also accepts @template-invariant as an explicit alias for the plain, unrestricted @template.

@template is not a phpDocumentor or PSR tag. It comes from the generics conventions that PHPStan and Psalm each adopted independently: PHPStan's generics guide and Psalm's templated annotations.

05 July 2026