psalm icon indicating copy to clipboard operation
psalm copied to clipboard

Type inference from callback where template type is boolean

Open trowski opened this issue 11 months ago • 1 comments

I'm not exactly sure what's going on here, I'd expect the inferred return type from Cache::compute() to be boolean, but Psalm is saying it must be one of true or false.

https://psalm.dev/r/b8431d7429

trowski avatar Mar 06 '24 19:03 trowski

I found these snippets:

https://psalm.dev/r/b8431d7429
<?php

/**
 * @template T
 */
class CacheResult {
    /** @param T $value */
    public function __construct(public readonly mixed $value) {} 
}
    

class Cache {
    /**
     * @template T
     * @param callable(string):CacheResult<T> $factory
     * @return T
     */
    public function compute(string $key, callable $factory) {
        return $factory($key)->value;
    }
}

$cache = new Cache();

$cache->compute('key',  function (): CacheResult {
    if (time() & 1) {
        return new CacheResult(true);
    }
    
    return new CacheResult(false);
});
Psalm output (using commit 3600d51):

ERROR: InvalidArgument - 25:9 - Incompatible types found for T (must have only one of false, true)

psalm-github-bot[bot] avatar Mar 06 '24 19:03 psalm-github-bot[bot]