如何解决PHPStan报错:$astTreeData的array迭代类型未指定值类型
PHPStan 数组迭代类型报错修复方案
我编写了如下格式化函数:
function prepareValue(mixed $value): string { ... return "{$value}"; } /** * @param array<int, array> $astTreeData * @return string */ function makeFormattedDiff(array $astTreeData): string { $statusTree = [ 'added' => function (string $path, array $node) { {some code...} return "Property '{$path}' was added with value: {$value}"; }, 'deleted' => fn($path) => "Property '{$path}' was removed", 'nested' => function (string $path, array $node, callable $iterRender) { {some code...} return $iterRender($children, $path); }, 'changed' => function (string $path, array $node) { {some code...} return "Property '{$path}' was updated. From {$valueBefore} to {$valueAfter}"; }, 'unchanged' => fn() => [], ]; /** * @param array<int, array> $diff * @return string */ $renderPlainDiff = function (array $diff, string|bool $pathComposition) use (&$renderPlainDiff, $statusTree) { $diffCopy = $diff; $lines = array_reduce( $diffCopy, /** * @param array<int, string> $acc * @param array<string, array> $node * @param array|null $initial * @return array */ function (array $acc, array $node, array|null $initial = []) use ( $renderPlainDiff, $pathComposition, $statusTree ) { {some code...} $diffTypeHandler = $statusTree[$status]; return flatten([$acc, $diffTypeHandler($newPath, $node, $renderPlainDiff)]); }, [] ); return implode("\n", $lines); }; return $renderPlainDiff($astTreeData, false); }
我已经通过PHPDoc注解与类型提示语法详细标注了所有参数和返回值类型,但PHPStan仍然抛出如下错误:Function Differ\Formatters\plainFormatter\makeFormattedDiff() has parameter $astTreeData with no value type specified in iterable type array
报错原因
这个报错的核心是数组泛型声明不完整:你写的array<int, array>只告诉PHPStan外层数组的键是整数、值为数组,但内层数组的键类型、值类型完全没有声明,PHPStan严格检查模式下不允许用无类型的裸array作为迭代器的值类型。
需要补充类型的位置
所有出现裸array作为迭代值类型的位置都要补全类型描述,具体清单:
- 函数入参
$astTreeData:当前array<int, array>的内层array未指定类型,临时消错可以改成array<int, array<string, mixed>>;如果要做更严格的类型检查,可以定义AST节点的具体结构形状,例如array<int, array{status: 'added'|'deleted'|'nested'|'changed'|'unchanged', key: string, value?: mixed, valueBefore?: mixed, valueAfter?: mixed, children?: array}>,明确每个节点的固定字段类型。 - 内部变量
$statusTree:缺少类型标注,它是键为状态字符串、值为对应处理回调的映射数组,需要标注为array<string, callable>。 - 状态处理闭包的
$node参数:added/nested/changed三个闭包都只写了array $node,未指定节点数组的内部结构,替换为前面定义的AST节点类型即可。 - 内部闭包
$renderPlainDiff的$diff参数:当前标注的array<int, array>和$astTreeData问题一致,补全内层数组类型即可。 array_reduce回调内的$node参数:PHPDoc里写的array<string, array>同样包含裸array,替换为AST节点类型即可。unchanged闭包的返回值:它固定返回空数组,建议标注返回类型为list<never>,避免PHPStan推断出模糊的数组类型。array_reduce回调的$initial参数:当前标注的array|null过于宽泛,和累加器$acc类型对应,应改为array<int, string>|null。
内容的提问来源于stack exchange,提问作者wakh
相关产品推荐
相关产品推荐

