Pslam errors with FlagBag
Opened this issue · 11 comments
I have some errors when I use the FlagBag
class and test within Psalm.
Example:
namespace App\Enum;
enum Permissions: int
{
case Execute = 1 << 0;
case Write = 1 << 1;
case Read = 1 << 2;
}
I then use this enumeration within FlagBag:
$flagBag = FlagBag::from(Permissions::class);
Pslam report this error:
ERROR: InvalidArgument - Argument 1 of Elao\Enum\FlagBag::from expects Elao\Enum\T|class-string<Elao\Enum\T>, App\Enum\Permissions::class provided (see https://psalm.dev/004)
FlagBag::from(Permissions::class);
We have annoted the Permissions class ?
does adding:
* @template T of \BackedEnum
to the FlagBag::from
method solves this?
Yes, with this change, Pslam does not more complain about invalid argument.
PR welcomed then :)
Hello,
I open this error again because Pslam complains about the following code:
private function getDefaultPermissions(): FlagBag
{
return FlagBag::from(Permissions::Execute , Permissions::Write, Permissions::Read);
}
Argument 2 of Elao\Enum\FlagBag::from expects Elao\Enum\T, but enum(App\Enum\Permissions::Execute) provided (see https://psalm.dev/004)
Argument 3 of Elao\Enum\FlagBag::from expects Elao\Enum\T, but enum(App\Enum\Permissions::SHOW) provided (see https://psalm.dev/004)
I have modified the from
function with this annotation:
/**
* @template E of \BackedEnum
* @param class-string<E>|E $enumOrType
* @param E ...$flags
* @return FlagBag<E>
*/
public static function from(string|\BackedEnum $enumOrType, \BackedEnum ...$flags): static
{
//...
}
And it work without error.
It seems the suggested code triggers an issue with PHPStan :
------ -----------------------------------------------------------------------------------------------------------------------------
Line FlagBag.php
------ -----------------------------------------------------------------------------------------------------------------------------
90 PHPDoc tag @return with type Elao\Enum\FlagBag<E of BackedEnum> is incompatible with native type static(Elao\Enum\FlagBag<T
of BackedEnum>).
------ -----------------------------------------------------------------------------------------------------------------------------
OK. I tested with a new specific PHPStan annotation and it's work for both (PHPStan and Pslam):
/**
* @param class-string<T>|T $enumOrType
*
* @phpstan-return FlagBag<T>
*
* @psalm-template E of \BackedEnum
* @psalm-param E ...$flags
* @psalm-return FlagBag<E>
*/
public static function from(string|\BackedEnum $enumOrType, \BackedEnum ...$flags): static
{
// ...
}
Any news about this ?
Thanks
Does
/**
* @param class-string<T>|T $enumOrType
* @param T ...$flags
*
* @return FlagBag<T>
*/
public static function from(string|\BackedEnum $enumOrType, \BackedEnum ...$flags): static
{
// ...
}
work? I don't get why we should add another generic type E
(nor specific annotations)
It is not working for me. I tried with the following annotations (using a new named template):
/**
* @template E of \BackedEnum
*
* @param class-string<E> $enumType
*
* @return FlagBag<E>
*/
public static function fromAll(string $enumType): FlagBag
{
// ...
}
And it's working! I do the same for the from
function:
/**
* @template E of \BackedEnum
*
* @param class-string<E>|E $enumOrType
* @param E ...$flags
*
* @return FlagBag<E>
*/
public static function from(string|\BackedEnum $enumOrType, \BackedEnum ...$flags): static
{
// ...
}
Great news! Would you be up to provide the PR?