PHP接口泛型实现报错:遇两类Psalm类型匹配错误
解决Psalm泛型接口实现的类型不匹配错误
问题原因
你遇到的ImplementedReturnTypeMismatch和MoreSpecificImplementedParamType错误,根源在于接口使用了方法级泛型:这种定义要求实现类的process方法能处理任意符合array<TKey, TValue>的数组,但你的实现类只接受特定结构的数组(比如array{string, list<int>}、list<string>),违反了里氏替换原则:
MoreSpecificImplementedParamType:接口允许接收任意键值数组,实现类却只接受更具体的子类型数组,不符合参数类型逆变的要求(参数应能兼容父类型)。ImplementedReturnTypeMismatch:接口允许返回任意对应类型的数组,实现类返回的是更具体的子类型,方法级泛型的约束导致Psalm判定返回类型不匹配。
解决方案
将泛型从方法级别移到接口级别,让每个实现类针对特定的数组类型实现接口,并通过@implements注解明确泛型参数。
修改后的代码示例
<?php /** * @template T of array */ interface Processor { /** * @param T $data * @return T */ public function process(array $data): array; } /** * @implements Processor<array{string, list<int>}> */ class QueryProcessor implements Processor { /** * @param array{string, list<int>} $data * @return array{string, list<int>} */ public function process(array $data): array { [$query, $parameters] = $data; // 数据处理逻辑 return [$query, $parameters]; } } /** * @implements Processor<list<string>> */ class OutputProcessor implements Processor { /** * @param list<string> $data * @return list<string> */ public function process(array $data): array { // 数据处理逻辑 return $data; } } $query = new QueryProcessor(); $query->process(['query', [1,2,3]]); $data = new OutputProcessor(); $data->process(['abc']);
说明
- 接口级泛型
@template T of array定义了接口针对任意数组类型T,每个实现类可以指定具体的数组结构作为T。 @implements注解告诉Psalm实现类对应的泛型参数,让Psalm能正确验证参数和返回值类型与接口约束匹配。- 这种设计既保留了接口的抽象性,又允许实现类针对特定数组结构做类型校验,符合类型系统的协变/逆变规则。
内容的提问来源于stack exchange,提问作者Extreme Fansubs
相关产品推荐
相关产品推荐

