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

PHPStan中@return T与@return Aclass为何报错情况不同?

PHPStan泛型注解报错原因及解决方法

问题根源

你用@template T of Aclass+@return T的泛型注解时,PHPStan报错的核心原因是:你的注解承诺了方法返回的实例类型,必须和传入的$param类名完全匹配,但实际代码里不管传什么参数都固定返回Bclass实例,这违反了泛型约束的约定。

两种注解的本质区别

  • @return Aclass:只是声明方法返回Aclass或它的任意子类,只要返回值是Aclass的子类就合法,不要求和传入参数对应。所以你返回固定的Bclass时,PHPStan不会报错。
  • @template T of Aclass + @return T:这是泛型约束,它的意思是:调用方法时传入哪个Aclass子类的类名,方法就必须返回该子类的实例。比如传入Cclass::class,就必须返回Cclass实例,而你现在硬返回Bclass,和泛型承诺的类型不匹配,所以PHPStan会报错。

解决方法

根据你的实际需求选一种:

1. 让工厂真正根据传入参数创建对应实例(符合泛型注解)

修改代码,让方法根据传入的类名实例化对象,这样就满足泛型约束:

abstract class Aclass {}
final class Bclass extends Aclass {}
final class Cclass extends Aclass {}

final class Factory {
    /**
     * @template T of Aclass
     * @param class-string<T> $param
     * @return T
     */
    public function create($param) {
        return new $param();
    }
}

2. 固定返回Bclass(不使用泛型)

如果你确实只能返回Bclass,那泛型注解就不合适,直接声明返回具体类型更准确:

abstract class Aclass {}
final class Bclass extends Aclass {}
final class Cclass extends Aclass {}

final class Factory {
    /**
     * @param class-string<Aclass> $param
     * @return Bclass
     */
    public function create($param) {
        // some kind of factory logic
        return new Bclass();
    }
}

或者保持原来的@return Aclass也可以,只是类型精度稍低。

内容的提问来源于stack exchange,提问作者Slava Basko

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 23:45:09