New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Impossible types are not excluded from inferred template type #7889
Comments
I found these snippets: https://psalm.dev/r/6c26fe7cfb<?php
/**
* @psalm-suppress InvalidReturnType
* @psalm-suppress UnusedParam
*
* @template A1
* @template A2
* @template A3
* @template R
* @param (
* (array<string> & array{callable(A1): A2, callable(A2): A3, callable(A3): R})
* | array{callable(A1): A2, callable(A2): R}
* | (array{2: null} & array{callable(A1): R})
* ) $callbacks
* @psalm-return callable(A1): R
*/
function compose(array $callbacks): callable
{
}
/** @psalm-trace $a */
$a = compose([
fn (int $a): string => 'bar',
fn (string $a): string => 'foo',
fn (string $a): int => 7,
]);
/** @psalm-trace $b */
$b = $a(3);
|
Part of the problem here is that array shapes are not exhaustive, so the array passed to If you're ok using a plugin for this sort of thing though, both @klimick and @veewee did some work on |
Without using a plugin this almost works, but for some reason it resolves |
I found these snippets: https://psalm.dev/r/ada2824820<?php
/**
* @psalm-suppress InvalidReturnType
* @psalm-suppress UnusedParam
*
* @template A1
* @template A2
* @template A3
* @template R1
* @template R2
* @template R3
* @template C of (
* array{callable(A1): A2, callable(A2): A3, callable(A3): R3}
* | array{callable(A1): A2, callable(A2): R2}
* | array{callable(A1): R1}
* )
* @param C $callbacks
* @psalm-return (
* C is array{callable(A1): A2, callable(A2): A3, callable(A3): R3} ? (callable(A1): R3) : (
* C is array{callable(A1): A2, callable(A2): R2} ? (callable(A1): R2) : (
* (callable(A1): R1)
* )
* )
* )
*/
function compose(array $callbacks): callable
{
}
/** @psalm-trace $a */
$a = compose([
fn (int $a): string => 'bar',
fn (string $a): string => 'foo',
fn (string $a): int => 7,
]);
/** @psalm-trace $b */
$b = $a(3);
|
Yes a plugin is the way to go here. The result is most likely mixed because of this: (Haven't found the time to dive into it deeper) |
I'm sorry, but the code of the
You can see that the
So, the problem is, I'm calling the function with an |
With this example we can see that some param values aren't possibile, but the
R
template value is always assigned, probably because it's not inferred from the whole sum type.Expected: the
R
template should have the union of only possibile types.https://psalm.dev/r/6c26fe7cfb
The text was updated successfully, but these errors were encountered: