mirror of
https://github.com/danog/psalm.git
synced 2025-01-21 21:31:13 +01:00
Allow coercion from generic array to objectlike with possible keys
This commit is contained in:
parent
4065fa894f
commit
1282f74931
@ -350,10 +350,23 @@ class TypeChecker
|
||||
if ($container_type_part instanceof ObjectLike) {
|
||||
$generic_container_type_part = $container_type_part->getGenericArrayType();
|
||||
|
||||
$container_params_can_be_undefined = (bool) array_reduce(
|
||||
$container_type_part->properties,
|
||||
/**
|
||||
* @param bool $carry
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function ($carry, Type\Union $item) {
|
||||
return $carry || $item->possibly_undefined;
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
if (!$input_type_part instanceof ObjectLike
|
||||
&& !$input_type_part->type_params[0]->isMixed()
|
||||
&& !($input_type_part->type_params[1]->isEmpty()
|
||||
&& $generic_container_type_part->type_params[1]->possibly_undefined)
|
||||
&& $container_params_can_be_undefined)
|
||||
) {
|
||||
$all_types_contain = false;
|
||||
$type_coerced = true;
|
||||
|
@ -141,11 +141,8 @@ class ObjectLike extends \Psalm\Type\Atomic
|
||||
public function getGenericValueType()
|
||||
{
|
||||
$value_type = null;
|
||||
$any_value_defined = false;
|
||||
|
||||
foreach ($this->properties as $property) {
|
||||
$any_value_defined = $any_value_defined || !$property->possibly_undefined;
|
||||
|
||||
if ($value_type === null) {
|
||||
$value_type = clone $property;
|
||||
} else {
|
||||
@ -157,7 +154,7 @@ class ObjectLike extends \Psalm\Type\Atomic
|
||||
throw new \UnexpectedValueException('$value_type should not be null here');
|
||||
}
|
||||
|
||||
$value_type->possibly_undefined = !$any_value_defined;
|
||||
$value_type->possibly_undefined = false;
|
||||
|
||||
return $value_type;
|
||||
}
|
||||
@ -169,7 +166,6 @@ class ObjectLike extends \Psalm\Type\Atomic
|
||||
{
|
||||
$key_types = [];
|
||||
$value_type = null;
|
||||
$any_value_defined = false;
|
||||
|
||||
foreach ($this->properties as $key => $property) {
|
||||
if (is_int($key)) {
|
||||
@ -178,8 +174,6 @@ class ObjectLike extends \Psalm\Type\Atomic
|
||||
$key_types[] = new Type\Atomic\TString();
|
||||
}
|
||||
|
||||
$any_value_defined = $any_value_defined || !$property->possibly_undefined;
|
||||
|
||||
if ($value_type === null) {
|
||||
$value_type = clone $property;
|
||||
} else {
|
||||
@ -191,7 +185,7 @@ class ObjectLike extends \Psalm\Type\Atomic
|
||||
throw new \UnexpectedValueException('$value_type should not be null here');
|
||||
}
|
||||
|
||||
$value_type->possibly_undefined = !$any_value_defined;
|
||||
$value_type->possibly_undefined = false;
|
||||
|
||||
return new TArray([Type::combineTypes($key_types), $value_type]);
|
||||
}
|
||||
|
@ -256,13 +256,6 @@ class TypeCombinationTest extends TestCase
|
||||
'string',
|
||||
],
|
||||
],
|
||||
'combinePossiblyUndefinedKeysInMultipleArrays' => [
|
||||
'array{a?:string, b?:int, c?:string, d?:int}',
|
||||
[
|
||||
'array{a:string, b?:int}',
|
||||
'array{c:string, d?:int}',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -234,6 +234,14 @@ class TypeReconciliationTest extends TestCase
|
||||
|
||||
'unionContainsWithstring' => ['string', 'string|false'],
|
||||
'unionContainsWithFalse' => ['false', 'string|false'],
|
||||
'objectLikeTypeWithPossiblyUndefinedToGeneric' => [
|
||||
'array{0:array{a:string}, 1:array{c:string, e:string}}',
|
||||
'array<int, array<string, string>>'
|
||||
],
|
||||
'objectLikeTypeWithPossiblyUndefinedToEmpty' => [
|
||||
'array<empty, empty>',
|
||||
'array{a?:string, b?:string}',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user