PHP TypeLang Help

@template-contravariant

@template-contravariant declares a generic type parameter exactly like @template, but with the mirror-image promise of @template-covariant: the parameter is only ever used in "input" positions — accepted as an argument — never returned. That lets a static analyzer substitute in the other direction: a Comparator<Animal> is safe to use anywhere a Comparator<Dog> is expected, because anything that can compare animals in general can compare dogs in particular. Ordinary invariant @template parameters, and covariant ones, do not allow that substitution.

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

Parsing a @template-contravariant tag produces the same kind of tag as @template, exposing $parameter, $bound, and $default; see @template for what each of those means and how the "of" and "=" clauses work, and @template-covariant for the opposite variance.

final class TemplateContravariantTag extends TypeParameterTag { // Same $parameter/$bound/$default shape as TemplateTag. }

PHPStan supports contravariant template parameters — see its generics variance error reference, though that page does not spell out the @template-contravariant tag name verbatim. Psalm's own templated annotations page does not separately call out contravariance the way it does for covariant parameters.

05 July 2026