psalm icon indicating copy to clipboard operation
psalm copied to clipboard

Template of callable arguments

Open mathroc opened this issue 1 year ago • 1 comments

Feature request

When wrapping callable, we might want to describe that the callable we return will take the same arguments that the one we got as an argument. (see https://github.com/phpstan/phpstan/discussions/6813 for a short discussion on the subject)

Here is an exemple of what the syntax could look like:

https://psalm.dev/r/4e9c0e1d18

I like that it feels right to "expand" the array of types with callable(...A), but I know it might be confusing given callable(A...) as a different meaning


some other use cases for this feature:

/**
 * @template A1
 * @template Arest of array<mixed>
 * @template R
 * @param callable(A1, ...Arest): R
 * @return callable(...Arest): R
 */
function curry(callable $f, mixed $arg1): callable {
  return static fn (...$args) => $f($arg1, ...$args);
}

/**
 * @template A of array<mixed>
 * @template Rf
 * @template Rg
 * @param callable(...A): Rf $f
 * @param callable(Rf): Rg $g
 * @return callable(...A): Rg
function combine(callable $f, callable $g): callable {
   return static fn (...$args) => $g($f(...$args));
}

copied from https://github.com/phpstan/phpstan/issues/6873

mathroc avatar Sep 26 '24 12:09 mathroc

I found these snippets:

https://psalm.dev/r/4e9c0e1d18
<?php declare(strict_types = 1);

/**
 * @template A of array<mixed>
 * @param \Closure(...A): int $f
 * @return \Closure(...A): string
 */
function castToStringWrapper(\Closure $f): \Closure {
	return static fn (...$args): mixed => (string) $f(...$args);
}

$myRandomStringInt = castToStringWrapper(random_int(...));
Psalm output (using commit 16b24bd):

ERROR: InvalidArgument - 12:42 - Argument 1 of castToStringWrapper expects Closure(array<array-key, mixed>...):int, but pure-Closure(int, int):int provided

INFO: UnusedVariable - 12:1 - $myRandomStringInt is never referenced or the value is not used

psalm-github-bot[bot] avatar Sep 26 '24 12:09 psalm-github-bot[bot]