-
Notifications
You must be signed in to change notification settings - Fork 688
Open
Description
This code best describes it:
https://psalm.dev/r/f86eb62c76
/**
* @template A
*/
class Config {
/**
* @param (callable(): A)|null $x
*/
public function __construct($x = null)
{}
/**
* @template NewA
* @param (callable(): NewA)|null $x
* @return Config<NewA>
*/
public static function create($x = null)
{
return new self($x);
}
}
// Named constructor Tests:
/** @return Config<never>*/
function namedEmptyConfig() {
return Config::create();
}
/**
* This somehow resolves to mixed instead of never - even though the value is also null here:
* @return Config<never>
*/
function namedNullConfig() {
return Config::create(null);
}
// Test config constructor:
/**
* @return Config<never>
* Why does this work differently than the named constructor?
* I would expect "never" to be the result here, but instead it is mixed.
*/
function emptyConfig() {
return new Config();
}
/**
* @return Config<never>
* Same issue as in named constructor test - I'dd expect never here.
*/
function nullConfig() {
return new Config(null);
}
/** @return Config<string> */
function configured() {
return new Config(fn () => 'hello');
}I noticed this error when wrapping in yet another layer which applies conditional love to this config.
Something along the lines of
@return ConfigA is empty ? Foo : Bar
It never resolves to Foo, since it is not empty.
If I change it to: ConfigA is mixed it always resolves to Foo
Reactions are currently unavailable