Since PHPStan 1.6, it's possible to use Conditional Return Types, where I've been able to do things like:
/**
* @param string $x
* @return ($x is literal-string ? literal-string : string)
*/
public function isNull($x)
{
}
This takes the form of (<template param> is <union type> ? <union type> : <union type>)
.
While it's not possible to do more complicated conditions, it is possible to nest them (even if it gets a bit messy):
/**
* @param string $val
* @param string $x
* @param string $y
* @return ($val is literal-string ? ($x is literal-string ? ($y is literal-string ? literal-string : string) : string) : string)
*/
public function between($val, $x, $y)
{
}
But I'm not sure how to handle a Variadic Function Parameter, where the function can accept any number of values.
I'd like to return a literal-string
when all values are a literal-string
, otherwise return a string
.
Maybe something like the following (which does not work):
/**
* @param string ...$x
* @return ($x is array<literal-string> ? literal-string : string)
*/
function example(...$x) {
return implode(', ', $x);
}
Is this a limitation of the current implementation in PHPStan, or am I missing something?
This relates to the PHPStan Doctrine Extension, and Pull Request 324.
One option is to use a Dynamic Return Type Extension (which I might revert).
The solution is to use a
@template
, e.g.But this does not work with Doctrine ORM 2.x, because it uses
($x)
not(...$x)
for its arguments (source), which PR 9911 fixes for 3.x.