Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 6 additions & 17 deletions src/Illuminate/Collections/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -509,14 +509,9 @@ public function getOrPut($key, $value)
}

/**
* Group an associative array by a field or using a callback.
*
* @template TGroupKey of array-key
*
* @param (callable(TValue, TKey): TGroupKey)|array|string $groupBy
* @param bool $preserveKeys
* @return static<($groupBy is string ? array-key : ($groupBy is array ? array-key : TGroupKey)), static<($preserveKeys is true ? TKey : int), ($groupBy is array ? mixed : TValue)>>
* {@inheritDoc}
*/
#[\Override]
public function groupBy($groupBy, $preserveKeys = false)
{
if (! $this->useAsCallable($groupBy) && is_array($groupBy)) {
Expand Down Expand Up @@ -563,13 +558,9 @@ public function groupBy($groupBy, $preserveKeys = false)
}

/**
* Key an associative array by a field or using a callback.
*
* @template TNewKey of array-key
*
* @param (callable(TValue, TKey): TNewKey)|array|string $keyBy
* @return static<($keyBy is string ? array-key : ($keyBy is array ? array-key : TNewKey)), TValue>
* {@inheritDoc}
*/
#[\Override]
public function keyBy($keyBy)
{
$keyBy = $this->valueRetriever($keyBy);
Expand Down Expand Up @@ -1861,11 +1852,9 @@ public function count(): int
}

/**
* Count the number of items in the collection by a field or using a callback.
*
* @param (callable(TValue, TKey): array-key|\UnitEnum)|string|null $countBy
* @return static<array-key, int>
* {@inheritDoc}
*/
#[\Override]
public function countBy($countBy = null)
{
return new static($this->lazy()->countBy($countBy)->all());
Expand Down
15 changes: 10 additions & 5 deletions src/Illuminate/Collections/Enumerable.php
Original file line number Diff line number Diff line change
Expand Up @@ -519,21 +519,26 @@ public function get($key, $default = null);
/**
* Group an associative array by a field or using a callback.
*
* @template TGroupKey of array-key
* @template TGroupKey of array-key|\UnitEnum|\Stringable
*
* @param (callable(TValue, TKey): TGroupKey)|array|string $groupBy
* @param bool $preserveKeys
* @return static<($groupBy is string ? array-key : ($groupBy is array ? array-key : TGroupKey)), static<($preserveKeys is true ? TKey : int), ($groupBy is array ? mixed : TValue)>>
* @return static<
* ($groupBy is (array|string)
* ? array-key
* : (TGroupKey is \UnitEnum ? array-key : (TGroupKey is \Stringable ? string : TGroupKey))),
* static<($preserveKeys is true ? TKey : int), ($groupBy is array ? mixed : TValue)>
* >
*/
public function groupBy($groupBy, $preserveKeys = false);

/**
* Key an associative array by a field or using a callback.
*
* @template TNewKey of array-key
* @template TNewKey of array-key|\UnitEnum
*
* @param (callable(TValue, TKey): TNewKey)|array|string $keyBy
* @return static<($keyBy is string ? array-key : ($keyBy is array ? array-key : TNewKey)), TValue>
* @return static<($keyBy is (array|string) ? array-key : (TNewKey is \UnitEnum ? array-key : TNewKey)), TValue>
*/
public function keyBy($keyBy);

Expand Down Expand Up @@ -1222,7 +1227,7 @@ public function count(): int;
/**
* Count the number of items in the collection by a field or using a callback.
*
* @param (callable(TValue, TKey): array-key|\UnitEnum)|string|null $countBy
* @param (callable(TValue, TKey): (array-key|\UnitEnum))|string|null $countBy
* @return static<array-key, int>
*/
public function countBy($countBy = null);
Expand Down
23 changes: 6 additions & 17 deletions src/Illuminate/Collections/LazyCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -317,11 +317,9 @@ public function crossJoin(...$arrays)
}

/**
* Count the number of items in the collection by a field or using a callback.
*
* @param (callable(TValue, TKey): array-key|\UnitEnum)|string|null $countBy
* @return static<array-key, int>
* {@inheritDoc}
*/
#[\Override]
public function countBy($countBy = null)
{
$countBy = is_null($countBy)
Expand Down Expand Up @@ -565,27 +563,18 @@ public function get($key, $default = null)
}

/**
* Group an associative array by a field or using a callback.
*
* @template TGroupKey of array-key
*
* @param (callable(TValue, TKey): TGroupKey)|array|string $groupBy
* @param bool $preserveKeys
* @return static<($groupBy is string ? array-key : ($groupBy is array ? array-key : TGroupKey)), static<($preserveKeys is true ? TKey : int), ($groupBy is array ? mixed : TValue)>>
* {@inheritDoc}
*/
#[\Override]
public function groupBy($groupBy, $preserveKeys = false)
{
return $this->passthru('groupBy', func_get_args());
}

/**
* Key an associative array by a field or using a callback.
*
* @template TNewKey of array-key
*
* @param (callable(TValue, TKey): TNewKey)|array|string $keyBy
* @return static<($keyBy is string ? array-key : ($keyBy is array ? array-key : TNewKey)), TValue>
* {@inheritDoc}
*/
#[\Override]
public function keyBy($keyBy)
{
return new static(function () use ($keyBy) {
Expand Down
38 changes: 36 additions & 2 deletions types/Support/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -526,24 +526,33 @@ function ($collection, $count) {

assertType('Illuminate\Support\Collection<(int|string), Illuminate\Support\Collection<int, User>>', $collection->groupBy('name'));
assertType('Illuminate\Support\Collection<(int|string), Illuminate\Support\Collection<int, User>>', $collection->groupBy('name', true));
assertType('Illuminate\Support\Collection<(int|string), Illuminate\Support\Collection<int, mixed>>', $collection->groupBy(['name', 'email']));
assertType('Illuminate\Support\Collection<string, Illuminate\Support\Collection<int, User>>', $collection->groupBy(function ($user, $int) {
assertType('User', $user);
assertType('int', $int);

return 'foo';
}));
assertType('Illuminate\Support\Collection<int, Illuminate\Support\Collection<int, User>>', $collection->groupBy(static fn ($user) => 0));
assertType('Illuminate\Support\Collection<(int|string), Illuminate\Support\Collection<int, User>>', $collection->groupBy(static fn ($user) => Digit::One));
assertType('Illuminate\Support\Collection<(int|string), Illuminate\Support\Collection<int, User>>', $collection->groupBy(static fn ($user) => NamedDigit::One));
assertType('Illuminate\Support\Collection<(int|string), Illuminate\Support\Collection<int, User>>', $collection->groupBy(static fn ($user) => NumberedDigit::One));

assertType('Illuminate\Support\Collection<string, Illuminate\Support\Collection<string, User>>', $collection->keyBy(fn () => '')->groupBy(function ($user) {
assertType("Illuminate\Support\Collection<string, Illuminate\Support\Collection<'bar', User>>", $collection->keyBy(fn ($user) => 'bar')->groupBy(function ($user) {
return 'foo';
}, preserveKeys: true));

assertType('Illuminate\Support\Collection<(int|string), User>', $collection->keyBy('name'));
assertType('Illuminate\Support\Collection<string, User>', $collection->keyBy(function ($user, $int) {
assertType("Illuminate\Support\Collection<'foo', User>", $collection->keyBy(function ($user, $int) {
assertType('User', $user);
assertType('int', $int);

return 'foo';
}));
assertType("Illuminate\Support\Collection<0, User>", $collection->keyBy(static fn ($user): int => 0));
assertType('Illuminate\Support\Collection<(int|string), User>', $collection->keyBy(static fn ($user) => Digit::One));
assertType('Illuminate\Support\Collection<(int|string), User>', $collection->keyBy(static fn ($user) => NamedDigit::One));
assertType('Illuminate\Support\Collection<(int|string), User>', $collection->keyBy(static fn ($user) => NumberedDigit::One));

assertType('bool', $collection->has(0));
assertType('bool', $collection->has([0, 1]));
Expand Down Expand Up @@ -967,6 +976,10 @@ function ($collection, $count) {
assertType('Illuminate\Support\Collection<(int|string), int>', $collection->make([1])->countBy());
assertType('Illuminate\Support\Collection<(int|string), int>', $collection->make(['string' => 'string'])->countBy('string'));
assertType('Illuminate\Support\Collection<(int|string), int>', $collection->make([new User])->countBy('email'));
assertType('Illuminate\Support\Collection<(int|string), int>', $collection->make([new User])->countBy(static fn ($user) => 'email'));
assertType('Illuminate\Support\Collection<(int|string), int>', $collection->make([new User])->countBy(static fn ($user) => 0));
assertType('Illuminate\Support\Collection<(int|string), int>', $collection->make([new User])->countBy(static fn ($user) => Digit::One));
assertType('Illuminate\Support\Collection<(int|string), int>', $collection->make([new User])->countBy(static fn ($user) => NamedDigit::One));
assertType('Illuminate\Support\Collection<(int|string), int>', $collection->make(['string'])->countBy(function ($string, $int) {
assertType('string', $string);
assertType('int', $int);
Expand Down Expand Up @@ -1173,3 +1186,24 @@ public function getWithoutZebras(): Collection
assertType('Illuminate\Support\HigherOrderCollectionProxy<int, Animal>', $coll->unless);
assertType('Illuminate\Support\HigherOrderCollectionProxy<int, Animal>', $coll->until);
assertType('Illuminate\Support\HigherOrderCollectionProxy<int, Animal>', $coll->when);

enum Digit
{
case One;
case Two;
case Three;
}

enum NamedDigit: string
{
case One = 'one';
case Two = 'two';
case Three = 'three';
}

enum NumberedDigit: int
{
case One = 1;
case Two = 2;
case Three = 3;
}
42 changes: 39 additions & 3 deletions types/Support/LazyCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -419,23 +419,33 @@ public function toArray(): array

assertType('Illuminate\Support\LazyCollection<(int|string), Illuminate\Support\LazyCollection<int, User>>', $collection->groupBy('name'));
assertType('Illuminate\Support\LazyCollection<(int|string), Illuminate\Support\LazyCollection<int, User>>', $collection->groupBy('name', true));
assertType('Illuminate\Support\LazyCollection<(int|string), Illuminate\Support\LazyCollection<int, mixed>>', $collection->groupBy(['name', 'email']));
assertType('Illuminate\Support\LazyCollection<string, Illuminate\Support\LazyCollection<int, User>>', $collection->groupBy(function ($user, $int) {
assertType('User', $user);
assertType('int', $int);

return 'foo';
}));
assertType('Illuminate\Support\LazyCollection<string, Illuminate\Support\LazyCollection<string, User>>', $collection->keyBy(fn () => '')->groupBy(function ($user) {
assertType('Illuminate\Support\LazyCollection<int, Illuminate\Support\LazyCollection<int, User>>', $collection->groupBy(static fn ($user) => 0));
assertType('Illuminate\Support\LazyCollection<(int|string), Illuminate\Support\LazyCollection<int, User>>', $collection->groupBy(static fn ($user) => Digit::One));
assertType('Illuminate\Support\LazyCollection<(int|string), Illuminate\Support\LazyCollection<int, User>>', $collection->groupBy(static fn ($user) => NamedDigit::One));
assertType('Illuminate\Support\LazyCollection<(int|string), Illuminate\Support\LazyCollection<int, User>>', $collection->groupBy(static fn ($user) => NumberedDigit::One));

assertType("Illuminate\Support\LazyCollection<string, Illuminate\Support\LazyCollection<'bar', User>>", $collection->keyBy(fn ($user) => 'bar')->groupBy(function ($user) {
return 'foo';
}, true));
}, preserveKeys: true));

assertType('Illuminate\Support\LazyCollection<(int|string), User>', $collection->keyBy('name'));
assertType('Illuminate\Support\LazyCollection<string, User>', $collection->keyBy(function ($user, $int) {
assertType("Illuminate\Support\LazyCollection<'foo', User>", $collection->keyBy(function ($user, $int) {
assertType('User', $user);
assertType('int', $int);

return 'foo';
}));
assertType("Illuminate\Support\LazyCollection<0, User>", $collection->keyBy(static fn ($user): int => 0));
assertType('Illuminate\Support\LazyCollection<(int|string), User>', $collection->keyBy(static fn ($user) => Digit::One));
assertType('Illuminate\Support\LazyCollection<(int|string), User>', $collection->keyBy(static fn ($user) => NamedDigit::One));
assertType('Illuminate\Support\LazyCollection<(int|string), User>', $collection->keyBy(static fn ($user) => NumberedDigit::One));

assertType('bool', $collection->has(0));
assertType('bool', $collection->has([0, 1]));
Expand Down Expand Up @@ -831,6 +841,11 @@ public function toArray(): array

assertType('Illuminate\Support\LazyCollection<(int|string), int>', $collection->make([1])->countBy());
assertType('Illuminate\Support\LazyCollection<(int|string), int>', $collection->make(['string' => 'string'])->countBy('string'));
assertType('Illuminate\Support\LazyCollection<(int|string), int>', $collection->make([new User])->countBy('email'));
assertType('Illuminate\Support\LazyCollection<(int|string), int>', $collection->make([new User])->countBy(static fn ($user) => 'email'));
assertType('Illuminate\Support\LazyCollection<(int|string), int>', $collection->make([new User])->countBy(static fn ($user) => 0));
assertType('Illuminate\Support\LazyCollection<(int|string), int>', $collection->make([new User])->countBy(static fn ($user) => Digit::One));
assertType('Illuminate\Support\LazyCollection<(int|string), int>', $collection->make([new User])->countBy(static fn ($user) => NamedDigit::One));
assertType('Illuminate\Support\LazyCollection<(int|string), int>', $collection->make(['string'])->countBy(function ($string, $int) {
assertType('string', $string);
assertType('int', $int);
Expand Down Expand Up @@ -968,3 +983,24 @@ public function getWithoutZebras(): LazyCollection
assertType('Illuminate\Support\HigherOrderCollectionProxy<int, LazyAnimal>', $coll->unless);
assertType('Illuminate\Support\HigherOrderCollectionProxy<int, LazyAnimal>', $coll->until);
assertType('Illuminate\Support\HigherOrderCollectionProxy<int, LazyAnimal>', $coll->when);

enum Digit
{
case One;
case Two;
case Three;
}

enum NamedDigit: string
{
case One = 'one';
case Two = 'two';
case Three = 'three';
}

enum NumberedDigit: int
{
case One = 1;
case Two = 2;
case Three = 3;
}