使用 psalm 扩展接口的泛型
Extend a generic of an interface using psalm
我正在习惯使用 psalm,但我遇到了一个问题。我已经在 C# 中有了这个结构,它对我很有效。我真的不知道如何使用 psalm 解决这个问题。
我有一个 ContextInterface
和另一个实现它。
interface ContextInterface { public function getProductId(): int; }
interface SingleContextInterface extends ContextInterface { public function getWidth(): int; }
此外,我还为他们提供了策略界面。
/**
* @template-covariant T as ContextInterface
* @psalm-immutable
*/
interface CalculatorInterface
{
/**
* @psalm-param T $context
*/
public function getPrice(ContextInterface $context): int;
}
/**
* @template T as SingleContextInterface
* @template-extends CalculatorInterface<T>
* @psalm-immutable
*/
interface SingleDimensionalPriceCalculator extends CalculatorInterface { }
还有一个 class 实现接口:
/**
* @template T as SingleContextInterface
* @template-implements SingleDimensionalPriceCalculator<T>
* @psalm-immutable
*/
class SingleDimensionCalculator implements SingleDimensionalPriceCalculator
{
/**
* @psalm-param SingleContextInterface $context
*/
public function getPrice(ContextInterface $context): int
{
$context->getWidth();
return 1;
}
}
对于 getWidth()
方法调用,我收到以下错误:
ERROR: ImpureMethodCall - 37:19 - Cannot call an possibly-mutating method SingleContextInterface::getWidth from a mutation-free context
上的例子
当然实际案例更复杂,包含的接口也更多
我想,问题是我将 CalculatorInterface
上的模板标记为协变。我可以在没有协变的情况下扩展它。
示例 psalm.dev
我正在习惯使用 psalm,但我遇到了一个问题。我已经在 C# 中有了这个结构,它对我很有效。我真的不知道如何使用 psalm 解决这个问题。
我有一个 ContextInterface
和另一个实现它。
interface ContextInterface { public function getProductId(): int; }
interface SingleContextInterface extends ContextInterface { public function getWidth(): int; }
此外,我还为他们提供了策略界面。
/**
* @template-covariant T as ContextInterface
* @psalm-immutable
*/
interface CalculatorInterface
{
/**
* @psalm-param T $context
*/
public function getPrice(ContextInterface $context): int;
}
/**
* @template T as SingleContextInterface
* @template-extends CalculatorInterface<T>
* @psalm-immutable
*/
interface SingleDimensionalPriceCalculator extends CalculatorInterface { }
还有一个 class 实现接口:
/**
* @template T as SingleContextInterface
* @template-implements SingleDimensionalPriceCalculator<T>
* @psalm-immutable
*/
class SingleDimensionCalculator implements SingleDimensionalPriceCalculator
{
/**
* @psalm-param SingleContextInterface $context
*/
public function getPrice(ContextInterface $context): int
{
$context->getWidth();
return 1;
}
}
对于 getWidth()
方法调用,我收到以下错误:
ERROR: ImpureMethodCall - 37:19 - Cannot call an possibly-mutating method SingleContextInterface::getWidth from a mutation-free context
当然实际案例更复杂,包含的接口也更多
我想,问题是我将 CalculatorInterface
上的模板标记为协变。我可以在没有协变的情况下扩展它。
示例 psalm.dev