Skip to content

Commit 14155b6

Browse files
[9.x] Generic Type for Illuminate\Support\Fluent (#40273)
* wip Signed-off-by: Mior Muhammad Zaki <[email protected]> * wip Signed-off-by: Mior Muhammad Zaki <[email protected]> * Implements existing generic interfaces Co-authored-by: Nuno Maduro <[email protected]>
1 parent ac7e72a commit 14155b6

File tree

2 files changed

+52
-22
lines changed

2 files changed

+52
-22
lines changed

src/Illuminate/Support/Fluent.php

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,26 @@
77
use Illuminate\Contracts\Support\Jsonable;
88
use JsonSerializable;
99

10+
/**
11+
* @template TKey of array-key
12+
* @template TValue
13+
*
14+
* @implements \Illuminate\Contracts\Support\Arrayable<TKey, TValue>
15+
* @implements \ArrayAccess<TKey, TValue>
16+
*/
1017
class Fluent implements Arrayable, ArrayAccess, Jsonable, JsonSerializable
1118
{
1219
/**
1320
* All of the attributes set on the fluent instance.
1421
*
15-
* @var array
22+
* @var array<TKey, TValue>
1623
*/
1724
protected $attributes = [];
1825

1926
/**
2027
* Create a new fluent instance.
2128
*
22-
* @param array|object $attributes
29+
* @param iterable<TKey, TValue> $attributes
2330
* @return void
2431
*/
2532
public function __construct($attributes = [])
@@ -32,9 +39,11 @@ public function __construct($attributes = [])
3239
/**
3340
* Get an attribute from the fluent instance.
3441
*
35-
* @param string $key
36-
* @param mixed $default
37-
* @return mixed
42+
* @template TGetDefault
43+
*
44+
* @param TKey $key
45+
* @param TGetDefault|(\Closure(): TGetDefault) $default
46+
* @return TValue|TGetDefault
3847
*/
3948
public function get($key, $default = null)
4049
{
@@ -48,7 +57,7 @@ public function get($key, $default = null)
4857
/**
4958
* Get the attributes from the fluent instance.
5059
*
51-
* @return array
60+
* @return array<TKey, TValue>
5261
*/
5362
public function getAttributes()
5463
{
@@ -58,7 +67,7 @@ public function getAttributes()
5867
/**
5968
* Convert the fluent instance to an array.
6069
*
61-
* @return array
70+
* @return array<TKey, TValue>
6271
*/
6372
public function toArray()
6473
{
@@ -68,7 +77,7 @@ public function toArray()
6877
/**
6978
* Convert the object into something JSON serializable.
7079
*
71-
* @return array
80+
* @return array<TKey, TValue>
7281
*/
7382
#[\ReturnTypeWillChange]
7483
public function jsonSerialize()
@@ -90,7 +99,7 @@ public function toJson($options = 0)
9099
/**
91100
* Determine if the given offset exists.
92101
*
93-
* @param string $offset
102+
* @param TKey $offset
94103
* @return bool
95104
*/
96105
#[\ReturnTypeWillChange]
@@ -102,8 +111,8 @@ public function offsetExists($offset)
102111
/**
103112
* Get the value for a given offset.
104113
*
105-
* @param string $offset
106-
* @return mixed
114+
* @param TKey $offset
115+
* @return TValue|null
107116
*/
108117
#[\ReturnTypeWillChange]
109118
public function offsetGet($offset)
@@ -114,8 +123,8 @@ public function offsetGet($offset)
114123
/**
115124
* Set the value at the given offset.
116125
*
117-
* @param string $offset
118-
* @param mixed $value
126+
* @param TKey $offset
127+
* @param TValue $value
119128
* @return void
120129
*/
121130
#[\ReturnTypeWillChange]
@@ -127,7 +136,7 @@ public function offsetSet($offset, $value)
127136
/**
128137
* Unset the value at the given offset.
129138
*
130-
* @param string $offset
139+
* @param TKey $offset
131140
* @return void
132141
*/
133142
#[\ReturnTypeWillChange]
@@ -139,8 +148,8 @@ public function offsetUnset($offset)
139148
/**
140149
* Handle dynamic calls to the fluent instance to set attributes.
141150
*
142-
* @param string $method
143-
* @param array $parameters
151+
* @param TKey $method
152+
* @param array{0: ?TValue} $parameters
144153
* @return $this
145154
*/
146155
public function __call($method, $parameters)
@@ -153,8 +162,8 @@ public function __call($method, $parameters)
153162
/**
154163
* Dynamically retrieve the value of an attribute.
155164
*
156-
* @param string $key
157-
* @return mixed
165+
* @param TKey $key
166+
* @return TValue|null
158167
*/
159168
public function __get($key)
160169
{
@@ -164,8 +173,8 @@ public function __get($key)
164173
/**
165174
* Dynamically set the value of an attribute.
166175
*
167-
* @param string $key
168-
* @param mixed $value
176+
* @param TKey $key
177+
* @param TValue $value
169178
* @return void
170179
*/
171180
public function __set($key, $value)
@@ -176,7 +185,7 @@ public function __set($key, $value)
176185
/**
177186
* Dynamically check if an attribute is set.
178187
*
179-
* @param string $key
188+
* @param TKey $key
180189
* @return bool
181190
*/
182191
public function __isset($key)
@@ -187,7 +196,7 @@ public function __isset($key)
187196
/**
188197
* Dynamically unset an attribute.
189198
*
190-
* @param string $key
199+
* @param TKey $key
191200
* @return void
192201
*/
193202
public function __unset($key)

types/Support/Fluent.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
use Illuminate\Support\Fluent;
4+
use function PHPStan\Testing\assertType;
5+
6+
$fluent = new Fluent(['name' => 'Taylor', 'age' => 25, 'user' => new User]);
7+
8+
assertType('Illuminate\Support\Fluent<string, int|string|User>', $fluent);
9+
assertType('Illuminate\Support\Fluent<string, string>', new Fluent(['name' => 'Taylor']));
10+
assertType('Illuminate\Support\Fluent<string, int>', new Fluent(['age' => 25]));
11+
assertType('Illuminate\Support\Fluent<string, User>', new Fluent(['user' => new User]));
12+
13+
assertType('int|string|User|null', $fluent['name']);
14+
assertType('int|string|User|null', $fluent['age']);
15+
assertType('int|string|User|null', $fluent['age']);
16+
assertType('int|string|User|null', $fluent->get('name'));
17+
assertType('int|string|User|null', $fluent->get('foobar'));
18+
assertType('int|string|User', $fluent->get('foobar', 'zonda'));
19+
assertType('array<string, int|string|User>', $fluent->getAttributes());
20+
assertType('array<string, int|string|User>', $fluent->toArray());
21+
assertType('array<string, int|string|User>', $fluent->jsonSerialize());

0 commit comments

Comments
 (0)