Description
Laravel Version
12.13.0
PHP Version
8.2.15
Database Driver & Version
No response
Description
Using Larastan v3.1.0
When using \Illuminate\Support\Collection, groupBy method returns totally different structure from what dumpPhpDocType reports
Having standard non-union type, group by returns the correct structure as reported by dumpPhpDocType() function.
/** @var Collection<int, array{'a': int}> $nonUnionCollection */
$nonUnionCollection = collect([ ['a' => 1], ['a' => 2] ]);
dumpPhpDocType($nonUnionCollection->groupBy(fn ($someArray) => 'singleGroup'));
dumpPhpDocType($nonUnionCollection->first());
Dumped type: Illuminate\Support\Collection<string, Illuminate\Support\Collection<int, array{a: int}>>
Dumped type: array{a: int}|null
That matches the expected output of:
Illuminate\Support\Collection {
"singleGroup" => Illuminate\Support\Collection {
0 => [
"a" => 1,
],
1 => [
"a" => 1,
],
...
}
}
I also dumped ->first()
to see it gets the correct type, and it does
However, when trying to do a group by on union of two collections, group by returns the incorrect structure from reported dumpPhpDocType() function.
/** @var Collection<int, array{'a': int}> | Collection<int, array{'b': int}> $unionCollection */
$unionCollection = collect([ ['a' => 1], ['a' => 2] ]);
dumpPhpDocType($unionCollection->groupBy(fn ($someArray) => 'singleGroup'));
dumpPhpDocType($unionCollection->first());
Dumped type: Illuminate\Support\Collection<int, array{a: int}>|Illuminate\Support\Collection<int, array{b: int}>
Dumped type: array{a: int}|array{b: int}|null
The actual output is:
Illuminate\Support\Collection {
"singleGroup" => Illuminate\Support\Collection {
0 => [
"a" => 1,
],
1 => [
"a" => 1,
],
...
}
}
or
Illuminate\Support\Collection {
"singleGroup" => Illuminate\Support\Collection {
0 => [
"b" => 1,
],
1 => [
"b" => 1,
],
...
}
}
The return type of that collection group by on union type is the same as the collection union type itself. It should been something like:
Illuminate\Support\Collection<string, Illuminate\Support\Collection<int, array{a: int}>>|Illuminate\Support\Collection<string, Illuminate\Support\Collection<int, array{a: int}>>
When dumping the type of the first element, it actually gave the union type from both collections, so i assume it is something to do with the type hinting of the group by method
Steps To Reproduce
As described in Description.