Skip to content

Commit d0ac2bf

Browse files
authored
feat: add generics to Container methods (#54543)
1 parent 454eb0d commit d0ac2bf

File tree

7 files changed

+156
-23
lines changed

7 files changed

+156
-23
lines changed

src/Illuminate/Container/Container.php

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -488,9 +488,11 @@ public function extend($abstract, Closure $closure)
488488
/**
489489
* Register an existing instance as shared in the container.
490490
*
491+
* @template TInstance of mixed
492+
*
491493
* @param string $abstract
492-
* @param mixed $instance
493-
* @return mixed
494+
* @param TInstance $instance
495+
* @return TInstance
494496
*/
495497
public function instance($abstract, $instance)
496498
{
@@ -719,8 +721,10 @@ protected function getClassForCallable($callback)
719721
/**
720722
* Get a closure to resolve the given type from the container.
721723
*
722-
* @param string $abstract
723-
* @return \Closure
724+
* @template TClass
725+
*
726+
* @param string|class-string<TClass> $abstract
727+
* @return ($abstract is class-string<TClass> ? \Closure(): TClass : \Closure(): mixed)
724728
*/
725729
public function factory($abstract)
726730
{
@@ -730,9 +734,11 @@ public function factory($abstract)
730734
/**
731735
* An alias function name for make().
732736
*
733-
* @param string|callable $abstract
737+
* @template TClass
738+
*
739+
* @param string|class-string<TClass>|callable $abstract
734740
* @param array $parameters
735-
* @return mixed
741+
* @return ($abstract is class-string<TClass> ? TClass : mixed)
736742
*
737743
* @throws \Illuminate\Contracts\Container\BindingResolutionException
738744
*/
@@ -744,9 +750,11 @@ public function makeWith($abstract, array $parameters = [])
744750
/**
745751
* Resolve the given type from the container.
746752
*
747-
* @param string $abstract
753+
* @template TClass
754+
*
755+
* @param string|class-string<TClass> $abstract
748756
* @param array $parameters
749-
* @return mixed
757+
* @return ($abstract is class-string<TClass> ? TClass : mixed)
750758
*
751759
* @throws \Illuminate\Contracts\Container\BindingResolutionException
752760
*/
@@ -758,7 +766,10 @@ public function make($abstract, array $parameters = [])
758766
/**
759767
* {@inheritdoc}
760768
*
761-
* @return mixed
769+
* @template TClass
770+
*
771+
* @param string|class-string<TClass> $id
772+
* @return ($id is class-string<TClass> ? TClass : mixed)
762773
*/
763774
public function get(string $id)
764775
{
@@ -776,10 +787,12 @@ public function get(string $id)
776787
/**
777788
* Resolve the given type from the container.
778789
*
779-
* @param string|callable $abstract
790+
* @template TClass
791+
*
792+
* @param string|class-string<TClass>|callable $abstract
780793
* @param array $parameters
781794
* @param bool $raiseEvents
782-
* @return mixed
795+
* @return ($abstract is class-string<TClass> ? TClass : mixed)
783796
*
784797
* @throws \Illuminate\Contracts\Container\BindingResolutionException
785798
* @throws \Illuminate\Contracts\Container\CircularDependencyException
@@ -919,8 +932,10 @@ protected function isBuildable($concrete, $abstract)
919932
/**
920933
* Instantiate a concrete instance of the given type.
921934
*
922-
* @param \Closure|string $concrete
923-
* @return mixed
935+
* @template TClass
936+
*
937+
* @param \Closure(static, array): TClass|class-string<TClass> $concrete
938+
* @return TClass
924939
*
925940
* @throws \Illuminate\Contracts\Container\BindingResolutionException
926941
* @throws \Illuminate\Contracts\Container\CircularDependencyException

src/Illuminate/Contracts/Container/Container.php

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,16 @@
77

88
interface Container extends ContainerInterface
99
{
10+
/**
11+
* {@inheritdoc}
12+
*
13+
* @template TClass
14+
*
15+
* @param string|class-string<TClass> $id
16+
* @return ($id is class-string<TClass> ? TClass : mixed)
17+
*/
18+
public function get(string $id);
19+
1020
/**
1121
* Determine if the given abstract type has been bound.
1222
*
@@ -122,9 +132,11 @@ public function extend($abstract, Closure $closure);
122132
/**
123133
* Register an existing instance as shared in the container.
124134
*
135+
* @template TInstance of mixed
136+
*
125137
* @param string $abstract
126-
* @param mixed $instance
127-
* @return mixed
138+
* @param TInstance $instance
139+
* @return TInstance
128140
*/
129141
public function instance($abstract, $instance);
130142

@@ -149,8 +161,10 @@ public function when($concrete);
149161
/**
150162
* Get a closure to resolve the given type from the container.
151163
*
152-
* @param string $abstract
153-
* @return \Closure
164+
* @template TClass
165+
*
166+
* @param string|class-string<TClass> $abstract
167+
* @return ($abstract is class-string<TClass> ? \Closure(): TClass : \Closure(): mixed)
154168
*/
155169
public function factory($abstract);
156170

@@ -164,9 +178,11 @@ public function flush();
164178
/**
165179
* Resolve the given type from the container.
166180
*
167-
* @param string $abstract
181+
* @template TClass
182+
*
183+
* @param string|class-string<TClass> $abstract
168184
* @param array $parameters
169-
* @return mixed
185+
* @return ($abstract is class-string<TClass> ? TClass : mixed)
170186
*
171187
* @throws \Illuminate\Contracts\Container\BindingResolutionException
172188
*/

src/Illuminate/Foundation/Application.php

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,9 +1043,11 @@ public function registerDeferredProvider($provider, $service = null)
10431043
/**
10441044
* Resolve the given type from the container.
10451045
*
1046-
* @param string $abstract
1046+
* @template TClass
1047+
*
1048+
* @param string|class-string<TClass> $abstract
10471049
* @param array $parameters
1048-
* @return mixed
1050+
* @return ($abstract is class-string<TClass> ? TClass : mixed)
10491051
*
10501052
* @throws \Illuminate\Contracts\Container\BindingResolutionException
10511053
*/
@@ -1059,10 +1061,12 @@ public function make($abstract, array $parameters = [])
10591061
/**
10601062
* Resolve the given type from the container.
10611063
*
1062-
* @param string $abstract
1064+
* @template TClass
1065+
*
1066+
* @param string|class-string<TClass>|callable $abstract
10631067
* @param array $parameters
10641068
* @param bool $raiseEvents
1065-
* @return mixed
1069+
* @return ($abstract is class-string<TClass> ? TClass : mixed)
10661070
*
10671071
* @throws \Illuminate\Contracts\Container\BindingResolutionException
10681072
* @throws \Illuminate\Contracts\Container\CircularDependencyException

types/Container/Container.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
use Illuminate\Config\Repository;
4+
use Illuminate\Container\Container;
5+
6+
use function PHPStan\Testing\assertType;
7+
8+
$container = resolve(Container::class);
9+
10+
assertType('stdClass', $container->instance('foo', new stdClass));
11+
12+
assertType('mixed', $container->get('foo'));
13+
assertType('Illuminate\Config\Repository', $container->get(Repository::class));
14+
15+
assertType('Closure(): mixed', $container->factory('foo'));
16+
assertType('Closure(): Illuminate\Config\Repository', $container->factory(Repository::class));
17+
18+
assertType('mixed', $container->make('foo'));
19+
assertType('Illuminate\Config\Repository', $container->make(Repository::class));
20+
21+
assertType('mixed', $container->makeWith('foo'));
22+
assertType('Illuminate\Config\Repository', $container->makeWith(Repository::class));
23+
24+
assertType('Illuminate\Config\Repository', $container->build(Repository::class));
25+
assertType('Illuminate\Config\Repository', $container->build(function (Container $container, array $parameters) {
26+
return new Repository($parameters);
27+
}));
28+
assertType('stdClass', $container->build(function () {
29+
return new stdClass();
30+
}));
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
use Illuminate\Config\Repository;
4+
use Illuminate\Contracts\Container\Container;
5+
6+
use function PHPStan\Testing\assertType;
7+
8+
$container = resolve(Container::class);
9+
10+
assertType('stdClass', $container->instance('foo', new stdClass));
11+
12+
assertType('mixed', $container->get('foo'));
13+
assertType('Illuminate\Config\Repository', $container->get(Repository::class));
14+
15+
assertType('Closure(): mixed', $container->factory('foo'));
16+
assertType('Closure(): Illuminate\Config\Repository', $container->factory(Repository::class));
17+
18+
assertType('mixed', $container->make('foo'));
19+
assertType('Illuminate\Config\Repository', $container->make(Repository::class));
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
use Illuminate\Config\Repository;
4+
use Illuminate\Contracts\Foundation\Application;
5+
6+
use function PHPStan\Testing\assertType;
7+
8+
$app = resolve(Application::class);
9+
10+
assertType('stdClass', $app->instance('foo', new stdClass));
11+
12+
assertType('mixed', $app->get('foo'));
13+
assertType('Illuminate\Config\Repository', $app->get(Repository::class));
14+
15+
assertType('Closure(): mixed', $app->factory('foo'));
16+
assertType('Closure(): Illuminate\Config\Repository', $app->factory(Repository::class));
17+
18+
assertType('mixed', $app->make('foo'));
19+
assertType('Illuminate\Config\Repository', $app->make(Repository::class));

types/Foundation/Application.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
use Illuminate\Config\Repository;
4+
use Illuminate\Foundation\Application;
5+
6+
use function PHPStan\Testing\assertType;
7+
8+
$app = resolve(Application::class);
9+
10+
assertType('stdClass', $app->instance('foo', new stdClass));
11+
12+
assertType('mixed', $app->get('foo'));
13+
assertType('Illuminate\Config\Repository', $app->get(Repository::class));
14+
15+
assertType('Closure(): mixed', $app->factory('foo'));
16+
assertType('Closure(): Illuminate\Config\Repository', $app->factory(Repository::class));
17+
18+
assertType('mixed', $app->make('foo'));
19+
assertType('Illuminate\Config\Repository', $app->make(Repository::class));
20+
21+
assertType('mixed', $app->makeWith('foo'));
22+
assertType('Illuminate\Config\Repository', $app->makeWith(Repository::class));
23+
24+
assertType('Illuminate\Config\Repository', $app->build(Repository::class));
25+
assertType('Illuminate\Config\Repository', $app->build(function (Application $app, array $parameters) {
26+
return new Repository($parameters);
27+
}));
28+
assertType('stdClass', $app->build(function () {
29+
return new stdClass();
30+
}));

0 commit comments

Comments
 (0)