-
Notifications
You must be signed in to change notification settings - Fork 663
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
Class template type on static method #5642
Comments
I found these snippets: https://psalm.dev/r/cdf35ba896<?php
class Enum {
public function __construct(
public int $val,
) {
}
}
/** @template T of Enum */
interface MultiEnumWithPairInterface {
/**
* @param list<T> $enums
* @return static
*/
public static function createFromList(array $enums);
}
class MultiEnum {
private int $value;
/**
* @param list<int> $values
*/
public final function __construct(array $values) {
$this->value = array_reduce(
$values,
static fn(int $acc, int $val): int => $acc | $val,
0,
);
}
/**
* @return static
*/
public static function createFromValue(int $val) {
return new static([$val]);
}
}
/** @template T */
trait MultiEnumWithPair {
/**
* @param list<T> $enums
* @return static
*/
public static function createFromList(array $enums) {
return static::createFromValue(1);
}
/**
* @param int $data
* @return static
*/
public static abstract function createFromValue(int $val);
}
class EnumABC extends Enum {
}
class EnumDEF extends Enum {
}
/**
* @template-implements MultiEnumWithPairInterface<EnumABC>
*/
class MultiEnumABC extends MultiEnum implements MultiEnumWithPairInterface {
/**
* @use MultiEnumWithPair<EnumABC>
*/
use MultiEnumWithPair;
}
$a = MultiEnumABC::createFromList([new EnumDEF(1)]);
https://psalm.dev/r/62775eb03c<?php
class Enum {
public function __construct(
public int $val,
) {
}
}
/** @template T of Enum */
interface MultiEnumWithPairInterface {
/**
* @template TT of T
* @param list<TT> $enums
* @return static
*/
public static function createFromList(array $enums);
}
class MultiEnum {
private int $value;
/**
* @param list<int> $values
*/
public final function __construct(array $values) {
$this->value = array_reduce(
$values,
static fn(int $acc, int $val): int => $acc | $val,
0,
);
}
/**
* @return static
*/
public static function createFromValue(int $val) {
return new static([$val]);
}
}
/** @template T */
trait MultiEnumWithPair {
/**
* @template TT of T
* @param list<TT> $enums
* @return static
*/
public static function createFromList(array $enums) {
return static::createFromValue(1);
}
/**
* @param int $data
* @return static
*/
public static abstract function createFromValue(int $val);
}
class EnumABC extends Enum {
}
class EnumDEF extends Enum {
}
/**
* @template-implements MultiEnumWithPairInterface<EnumABC>
*/
class MultiEnumABC extends MultiEnum implements MultiEnumWithPairInterface {
/**
* @use MultiEnumWithPair<EnumABC>
*/
use MultiEnumWithPair;
}
$a = MultiEnumABC::createFromList([new EnumDEF(1)]);
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi,
We encountered a similar issue to #4258 and #2751.
I see that some work has been done to avoid this issue as in 50fc50f but there is still an issue with
@param
annotation.Example of the issue (and a simplified use-case) is shown here: https://psalm.dev/r/cdf35ba896
The exact same code is working in PHPStan: https://phpstan.org/r/bcf918eb-626f-40cf-8b08-cbfa588f7b1f
Is there any reason why class level template parameters are forbidden in the
@param
annotation or is it a bug?It's not possible to replace it with
As that would loosen the type checking between the Enum and MultiEnum class.
I actually found a workaround using
@template TT of T
annotation instead on the class methods and I'm fine with such solution if it's the expected way of doing it but I'd at least add it to the docs.(Workaround: https://psalm.dev/r/62775eb03c)
Thank you!
The text was updated successfully, but these errors were encountered: