You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 04:41:15