Bug report
PHPStan incorrectly allows an array shape like array{name: string} to be assigned to a type like array{name: string, email?: string}
This is unsound because PHPStan arrays are unsealed by default. This means a value of type array{name: string} is only guaranteed to have a 'name' key of type string; it could also contain any other key, including an 'email' key of a non-string type.
When such a value is assigned to a variable expecting array{name: string, email?: string}, PHPStan fails to check for this potential conflict. It assumes the absence of the optional 'email' key, but doesn't validate that if the key is present in the source type, it has a compatible type.
<?php
class NotAString {}
/**
* The effective return type here is `array{name: string, ...}`.
* It might contain an 'email' key of any type.
*
* @return array{name: string}
*/
function x(): array {
return ['name' => 'string', 'email' => new NotAString()];
}
/**
* @return array{name: string, email?: string}
*/
function y(): array {
// This return should be invalid.
//
// The type `array{name: string}` from x() is not a subtype of
// `array{name: string, email?: string}` because x() could return an
// array with an 'email' key of an incompatible type.
return x();
}
Runtime failure: https://3v4l.org/espEJ
Code snippet that reproduces the problem
https://phpstan.org/r/f9f632b7-848f-4e16-b843-9aad2daec68b
Expected output
PHPStan should report an error on the return x(); line. It should recognize that array{name: string} is not safely assignable to array{name: string, email?: string} because the source type could contain an 'email' key that violates the target type's definition.
Did PHPStan help you today? Did it make you happy in any way?
No response
Bug report
PHPStan incorrectly allows an array shape like
array{name: string}to be assigned to a type likearray{name: string, email?: string}This is unsound because PHPStan arrays are unsealed by default. This means a value of type
array{name: string}is only guaranteed to have a'name'key of typestring; it could also contain any other key, including an'email'key of a non-string type.When such a value is assigned to a variable expecting
array{name: string, email?: string}, PHPStan fails to check for this potential conflict. It assumes the absence of the optional'email'key, but doesn't validate that if the key is present in the source type, it has a compatible type.Runtime failure: https://3v4l.org/espEJ
Code snippet that reproduces the problem
https://phpstan.org/r/f9f632b7-848f-4e16-b843-9aad2daec68b
Expected output
PHPStan should report an error on the
return x();line. It should recognize thatarray{name: string}is not safely assignable toarray{name: string, email?: string}because the source type could contain an'email'key that violates the target type's definition.Did PHPStan help you today? Did it make you happy in any way?
No response