From dae8777f16b0018da377b8d32a72fce4dff5362e Mon Sep 17 00:00:00 2001 From: Patrick Hesselberg Date: Wed, 13 Mar 2024 14:46:18 +0100 Subject: [PATCH 1/2] Add generics for Arr::first() --- src/Illuminate/Collections/Arr.php | 11 +++--- types/Support/Arr.php | 56 ++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 types/Support/Arr.php diff --git a/src/Illuminate/Collections/Arr.php b/src/Illuminate/Collections/Arr.php index a66f6adfcb14..a1f43e505a15 100644 --- a/src/Illuminate/Collections/Arr.php +++ b/src/Illuminate/Collections/Arr.php @@ -181,10 +181,13 @@ public static function exists($array, $key) /** * Return the first element in an array passing a given truth test. * - * @param iterable $array - * @param callable|null $callback - * @param mixed $default - * @return mixed + * @template TValue + * @template TFirstDefault + * + * @param iterable $array + * @param (callable(TValue): bool)|null $callback + * @param TFirstDefault|(\Closure(): TFirstDefault) $default + * @return TValue|TFirstDefault */ public static function first($array, callable $callback = null, $default = null) { diff --git a/types/Support/Arr.php b/types/Support/Arr.php new file mode 100644 index 000000000000..c2cd33580d95 --- /dev/null +++ b/types/Support/Arr.php @@ -0,0 +1,56 @@ + $iterable */ +$iterable = []; +/** @var Traversable $traversable */ +$traversable = []; + +assertType('User|null', Arr::first($array)); +assertType('User|null', Arr::first($array, function ($user) { + assertType('User', $user); + + return true; +})); +assertType('string|User', Arr::first($array, function ($user) { + assertType('User', $user); + + return false; +}, 'string')); +assertType('string|User', Arr::first($array, null, function () { + return 'string'; +})); + +assertType('User|null', Arr::first($iterable)); +assertType('User|null', Arr::first($iterable, function ($user) { + assertType('User', $user); + + return true; +})); +assertType('string|User', Arr::first($iterable, function ($user) { + assertType('User', $user); + + return false; +}, 'string')); +assertType('string|User', Arr::first($iterable, null, function () { + return 'string'; +})); + +assertType('User|null', Arr::first($traversable)); +assertType('User|null', Arr::first($traversable, function ($user) { + assertType('User', $user); + + return true; +})); +assertType('string|User', Arr::first($traversable, function ($user) { + assertType('User', $user); + + return false; +}, 'string')); +assertType('string|User', Arr::first($traversable, null, function () { + return 'string'; +})); From ccba6c1cb05abdab9c78a9b485f8cbe53a59e605 Mon Sep 17 00:00:00 2001 From: Patrick Hesselberg Date: Wed, 13 Mar 2024 15:50:52 +0100 Subject: [PATCH 2/2] Add TKey --- src/Illuminate/Collections/Arr.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Illuminate/Collections/Arr.php b/src/Illuminate/Collections/Arr.php index a1f43e505a15..5d473c26575b 100644 --- a/src/Illuminate/Collections/Arr.php +++ b/src/Illuminate/Collections/Arr.php @@ -181,11 +181,12 @@ public static function exists($array, $key) /** * Return the first element in an array passing a given truth test. * + * @template TKey * @template TValue * @template TFirstDefault * - * @param iterable $array - * @param (callable(TValue): bool)|null $callback + * @param iterable $array + * @param (callable(TValue, TKey): bool)|null $callback * @param TFirstDefault|(\Closure(): TFirstDefault) $default * @return TValue|TFirstDefault */