PhpStorm PHPDoc类型推断:如何让处理后数组保留原数组类型?
自动推断arrayToIdMap返回类型的实现方案
问题背景
现有PHP代码如下:
function arrayToIdMap(array $models) : array { $result = []; foreach ($models as $model) { /** @var BaseClassWithGetIdMethod $model **/ $result[$model->getId()] = $model; } return $result; } /** @var Car[] **/ $carList = getCarList(); /** @var Truck[] **/ $truckList = getTruckList(); /** @var Car[] **/ $carMap = arrayToIdMap($carList); /** @var Truck[] **/ $truckMap = arrayToIdMap($truckList);
目前每次调用arrayToIdMap都需要手动标注返回数组的类型,希望无需手动注释,让PhpStorm自动推断$carMap、$truckMap的类型与输入数组$carList、$truckList一致,即无需额外类型声明,PhpStorm能识别$carMap为Car[]类型,$truckMap为Truck[]类型。
可以实现,提供两种方案:
方案1:PHP 8.0+原生泛型语法
直接在函数定义中通过泛型约束类型,PhpStorm会自动推导返回类型:
/** * @template T of BaseClassWithGetIdMethod * @param T[] $models * @return array<int|string, T> */ function arrayToIdMap(array $models): array { $result = []; foreach ($models as $model) { $result[$model->getId()] = $model; } return $result; } /** @var Car[] **/ $carList = getCarList(); /** @var Truck[] **/ $truckList = getTruckList(); // PhpStorm自动推断$carMap为array<int|string, Car>(等价于Car[]) $carMap = arrayToIdMap($carList); // PhpStorm自动推断$truckMap为array<int|string, Truck>(等价于Truck[]) $truckMap = arrayToIdMap($truckList);
方案2:PHPDoc泛型注解(兼容PHP 7.4及以下)
如果项目使用较低版本PHP,通过PHPDoc的泛型标记也能让PhpStorm正确识别:
/** * @template T * @param array<T> $models * @return array<string|int, T> * @psalm-template T of BaseClassWithGetIdMethod */ function arrayToIdMap(array $models): array { $result = []; foreach ($models as $model) { /** @var BaseClassWithGetIdMethod $model **/ $result[$model->getId()] = $model; } return $result; } /** @var Car[] **/ $carList = getCarList(); /** @var Truck[] **/ $truckList = getTruckList(); // PhpStorm自动识别$carMap为Car[],$truckMap为Truck[] $carMap = arrayToIdMap($carList); $truckMap = arrayToIdMap($truckList);
效果验证
使用任一方案后,调用$carMap[$id]->someMethod()时,只要Car类存在该方法,PhpStorm不会抛出错误,说明类型推断生效。
内容的提问来源于stack exchange,提问作者cr001
相关产品推荐
相关产品推荐

