Skip to content
Permalink
Browse files

Add more specific key coercion rules when assigning to arrays

  • Loading branch information...
muglug committed Aug 27, 2019
1 parent 5a5629b commit aba365931164d0b4c1795d1cd50a0b395717a387
@@ -448,13 +448,18 @@ public static function getArrayAccessTypeGivenOffset(
|| ($type->type_params[1]->isMixed() && \is_string($key_value)))
&& $key_value !== null
) {
$from_string_key = $type->type_params[0]->isString();
$from_mixed_array = $type->type_params[1]->isMixed();
// ok, type becomes an ObjectLike
$array_type->removeType($type_string);
$type = new ObjectLike([$key_value => $from_mixed_array ? Type::getMixed() : Type::getEmpty()]);
if ($from_mixed_array) {
$type->had_mixed_value = true;
if ($from_string_key) {
$type->had_string_key = true;
}
}
$array_type->addType($type);
@@ -35,6 +35,13 @@ class ObjectLike extends \Psalm\Type\Atomic
*/
public $sealed = false;
/**
* Whether or not the previous array had an unknown key type
*
* @var bool
*/
public $had_string_key = false;
/**
* Whether or not to allow new properties to be asserted on the given array
*
@@ -180,10 +187,6 @@ public function canBeFullyExpressedInPhp()
*/
public function getGenericKeyType()
{
if ($this->had_mixed_value) {
return Type::getString();
}
$key_types = [];
foreach ($this->properties as $key => $_) {
@@ -196,6 +199,10 @@ public function getGenericKeyType()
}
}
if ($this->had_mixed_value) {
$key_types[] = $this->had_string_key ? new TString : new TArrayKey;
}
return TypeCombination::combineTypes($key_types);
}
@@ -232,10 +239,6 @@ public function getGenericValueType()
*/
public function getGenericArrayType()
{
if ($this->had_mixed_value) {
return new TNonEmptyArray([Type::getString(), Type::getMixed()]);
}
$key_types = [];
$value_type = null;
@@ -259,6 +262,12 @@ public function getGenericArrayType()
throw new \UnexpectedValueException('$value_type should not be null here');
}
if ($this->had_mixed_value) {
$key_types[] = $this->had_string_key ? new TString : new TArrayKey;
$value_type = Type::combineUnionTypes(Type::getMixed(), $value_type);
}
$value_type->possibly_undefined = false;
if ($this->sealed) {

0 comments on commit aba3659

Please sign in to comment.
You can’t perform that action at this time.