diff --git a/src/Type/TypeCombinator.php b/src/Type/TypeCombinator.php index 30820b98e0a..04c12b77256 100644 --- a/src/Type/TypeCombinator.php +++ b/src/Type/TypeCombinator.php @@ -107,6 +107,7 @@ public static function union(Type ...$types): Type return new NeverType(); } + $arrayTypes = []; $benevolentTypes = []; $benevolentUnionObject = null; // transform A | (B | C) to A | B | C @@ -128,10 +129,27 @@ public static function union(Type ...$types): Type if (!($types[$i] instanceof UnionType)) { continue; } - if ($types[$i]->isNormalized()) { + if ($types[$i] instanceof TemplateType) { continue; } - if ($types[$i] instanceof TemplateType) { + if ($types[$i]->isNormalized()) { + $innerTypes = $types[$i]->getTypes(); + foreach ($innerTypes as $key => $innerType) { + if ($innerType->isArray()->yes()) { + $arrayTypes[] = $innerType; + $typesCount++; + unset($innerTypes[$key]); + } + } + if (count($innerTypes) === 0) { + $typesCount--; + continue; + } + if (count($innerTypes) === 1) { + $types[] = $innerTypes[0]; + continue; + } + $types[$i] = new UnionType(array_values($innerTypes), true); continue; } @@ -144,7 +162,6 @@ public static function union(Type ...$types): Type return $types[0]; } - $arrayTypes = []; $scalarTypes = []; $hasGenericScalarTypes = []; for ($i = 0; $i < $typesCount; $i++) { @@ -326,14 +343,15 @@ private static function compareTypesInUnion(Type $a, Type $b): ?array if ($a instanceof IntegerRangeType && $b instanceof IntegerRangeType) { return null; } + if ($a instanceof ConstantArrayType && $b instanceof ConstantArrayType) { + return null; + } + if ($a instanceof HasOffsetValueType && $b instanceof HasOffsetValueType) { if ($a->getOffsetType()->equals($b->getOffsetType())) { return [new HasOffsetValueType($a->getOffsetType(), self::union($a->getValueType(), $b->getValueType())), null]; } } - if ($a instanceof ConstantArrayType && $b instanceof ConstantArrayType) { - return null; - } // simplify string[] | int[] to (string|int)[] if ($a instanceof IterableType && $b instanceof IterableType) {