PHPStan推断返回类型时未识别接口实现问题求助
解决PHPStan泛型类型不匹配问题
问题核心是PHPStan默认对泛型参数采用不变类型检查:即便LeadModel实现了LeadContract、Collection实现了Enumerable,Enumerable<int, LeadContract>和Collection<int, LeadModel>仍会被判定为不同类型。解决关键是给Enumerable的泛型参数声明协变。
步骤1:修正Enumerable接口的泛型标注
将Enumerable的第二个泛型参数标记为协变(使用@template-covariant),允许返回值的泛型参数被子类型替换:
/** * @template TKey of array-key * @template-covariant TValue */ interface Enumerable { // 接口方法定义 }
步骤2:确保Collection正确实现泛型接口
在Collection类上明确标注实现的泛型参数:
/** * @template TKey of array-key * @template TValue * @implements Enumerable<TKey, TValue> */ class Collection implements Enumerable { // 类实现逻辑 }
步骤3:验证Repository接口与实现类的类型标注
- LeadRepository接口保持原有方法签名:
interface LeadRepository { public function list(): Enumerable<int, LeadContract>; }
- 实现类的list方法可直接返回
Collection<int, LeadModel>,PHPStan会认可协变关系:
class LeadRepositoryImpl implements LeadRepository { public function list(): Collection<int, LeadModel> { // 业务逻辑,返回包含LeadModel实例的Collection return new Collection([1 => new LeadModel()]); } }
额外检查
- 确保PHPStan版本≥0.12(协变/逆变支持从该版本开始引入);
- 确认
LeadModel完全实现LeadContract接口,无方法遗漏或类型不匹配。
内容的提问来源于stack exchange,提问作者CristianHG
相关产品推荐
相关产品推荐

