8
8
use PHPStan \Type \Accessory \AccessoryArrayListType ;
9
9
use PHPStan \Type \Accessory \NonEmptyArrayType ;
10
10
use PHPStan \Type \ArrayType ;
11
+ use PHPStan \Type \ConditionalTypeForParameter ;
11
12
use PHPStan \Type \Constant \ConstantArrayTypeBuilder ;
12
13
use PHPStan \Type \Constant \ConstantIntegerType ;
13
14
use PHPStan \Type \DynamicFunctionReturnTypeExtension ;
17
18
use PHPStan \Type \Type ;
18
19
use PHPStan \Type \TypeCombinator ;
19
20
use PHPStan \Type \TypeUtils ;
21
+ use PHPStan \Type \UnionType ;
20
22
use function array_slice ;
21
23
use function count ;
22
24
@@ -73,7 +75,7 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
73
75
foreach ($ constantArray ->getKeyTypes () as $ i => $ keyType ) {
74
76
$ returnedArrayBuilder ->setOffsetValueType (
75
77
$ keyType ,
76
- $ valueType ,
78
+ $ this -> mapValueType ( $ constantArray -> getOffsetValueType ( $ keyType ), $ valueType) ,
77
79
$ constantArray ->isOptionalKey ($ i ),
78
80
);
79
81
}
@@ -88,24 +90,24 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
88
90
} else {
89
91
$ mappedArrayType = TypeCombinator::intersect (new ArrayType (
90
92
$ arrayType ->getIterableKeyType (),
91
- $ valueType ,
93
+ $ this -> mapValueType ( $ arrayType -> getIterableValueType (), $ valueType) ,
92
94
), ...TypeUtils::getAccessoryTypes ($ arrayType ));
93
95
}
94
96
} elseif ($ arrayType ->isArray ()->yes ()) {
95
97
$ mappedArrayType = TypeCombinator::intersect (new ArrayType (
96
98
$ arrayType ->getIterableKeyType (),
97
- $ valueType ,
99
+ $ this -> mapValueType ( $ arrayType -> getIterableValueType (), $ valueType) ,
98
100
), ...TypeUtils::getAccessoryTypes ($ arrayType ));
99
101
} else {
100
102
$ mappedArrayType = new ArrayType (
101
103
new MixedType (),
102
- $ valueType ,
104
+ $ this -> mapValueType ( $ arrayType -> getIterableValueType (), $ valueType) ,
103
105
);
104
106
}
105
107
} else {
106
108
$ mappedArrayType = TypeCombinator::intersect (new ArrayType (
107
109
new IntegerType (),
108
- $ valueType ,
110
+ $ this -> mapValueType ( $ arrayType -> getIterableValueType (), $ valueType) ,
109
111
), ...TypeUtils::getAccessoryTypes ($ arrayType ));
110
112
}
111
113
@@ -116,4 +118,26 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
116
118
return $ mappedArrayType ;
117
119
}
118
120
121
+ private function mapValueType (Type $ initialValue , Type $ returnType ): Type
122
+ {
123
+ $ newValues = [];
124
+ if ($ returnType instanceof UnionType) {
125
+ foreach ($ returnType ->getTypes () as $ type ) {
126
+ if ($ type instanceof ConditionalTypeForParameter) {
127
+ $ newValues [] = $ type ->toConditional ($ initialValue );
128
+ } else {
129
+ $ newValues [] = $ type ;
130
+ }
131
+ }
132
+
133
+ return TypeCombinator::union (...$ newValues );
134
+ }
135
+
136
+ if ($ returnType instanceof ConditionalTypeForParameter) {
137
+ return $ returnType ->toConditional ($ initialValue );
138
+ }
139
+
140
+ return $ returnType ;
141
+ }
142
+
119
143
}
0 commit comments