When spreading an array shape defined in doc blocks the optional array keys are no longer optional.
<?php declare(strict_types = 1);
/**
* @param array{page?: int, search?: string} $settings
*/
function test(array $settings = []): bool {
$copy = [...$settings];
\PHPStan\dumpType($copy); // Dumped type: array{page: int, search: string}
\PHPStan\dumpType($settings); // Dumped type: array{page?: int, search?: string}
return isset($copy['search']); // Offset 'search' on array{page: int, search: string} in isset() always exists and is not nullable.
}
test();
PHPStan should keep the optional information. The correct type for $copy would be array{page?: int, search?: string}
Bug report
When spreading an array shape defined in doc blocks the optional array keys are no longer optional.
Code snippet that reproduces the problem
https://phpstan.org/r/1ffb734d-5580-4593-a980-00f3dd0569ea
Expected output
PHPStan should keep the optional information. The correct type for
$copywould bearray{page?: int, search?: string}