176
176
* await($promise);
177
177
* ```
178
178
*
179
- * @param callable $function
180
- * @return callable(mixed ...): PromiseInterface<mixed>
179
+ * @template T
180
+ * @template A1 (any number of function arguments, see https://github.com/phpstan/phpstan/issues/8214)
181
+ * @template A2
182
+ * @template A3
183
+ * @template A4
184
+ * @template A5
185
+ * @param callable(A1,A2,A3,A4,A5): (PromiseInterface<T>|T) $function
186
+ * @return callable(A1=,A2=,A3=,A4=,A5=): PromiseInterface<T>
181
187
* @since 4.0.0
182
188
* @see coroutine()
183
189
*/
@@ -268,8 +274,9 @@ function async(callable $function): callable
268
274
* }
269
275
* ```
270
276
*
271
- * @param PromiseInterface $promise
272
- * @return mixed returns whatever the promise resolves to
277
+ * @template T
278
+ * @param PromiseInterface<T> $promise
279
+ * @return T returns whatever the promise resolves to
273
280
* @throws \Exception when the promise is rejected with an `Exception`
274
281
* @throws \Throwable when the promise is rejected with a `Throwable`
275
282
* @throws \UnexpectedValueException when the promise is rejected with an unexpected value (Promise API v1 or v2 only)
@@ -279,6 +286,8 @@ function await(PromiseInterface $promise): mixed
279
286
$ fiber = null ;
280
287
$ resolved = false ;
281
288
$ rejected = false ;
289
+
290
+ /** @var T $resolvedValue */
282
291
$ resolvedValue = null ;
283
292
$ rejectedThrowable = null ;
284
293
$ lowLevelFiber = \Fiber::getCurrent ();
@@ -292,6 +301,7 @@ function (mixed $value) use (&$resolved, &$resolvedValue, &$fiber, $lowLevelFibe
292
301
/** @var ?\Fiber<mixed,mixed,mixed,mixed> $fiber */
293
302
if ($ fiber === null ) {
294
303
$ resolved = true ;
304
+ /** @var T $resolvedValue */
295
305
$ resolvedValue = $ value ;
296
306
return ;
297
307
}
@@ -305,7 +315,7 @@ function (mixed $throwable) use (&$rejected, &$rejectedThrowable, &$fiber, $lowL
305
315
306
316
if (!$ throwable instanceof \Throwable) {
307
317
$ throwable = new \UnexpectedValueException (
308
- 'Promise rejected with unexpected value of type ' . (is_object ($ throwable ) ? get_class ($ throwable ) : gettype ($ throwable ))
318
+ 'Promise rejected with unexpected value of type ' . (is_object ($ throwable ) ? get_class ($ throwable ) : gettype ($ throwable )) /** @phpstan-ignore-line */
309
319
);
310
320
311
321
// avoid garbage references by replacing all closures in call stack.
@@ -592,9 +602,16 @@ function delay(float $seconds): void
592
602
* });
593
603
* ```
594
604
*
595
- * @param callable(mixed ...$args):(\Generator<mixed,PromiseInterface,mixed,mixed>|mixed) $function
605
+ * @template T
606
+ * @template TYield
607
+ * @template A1 (any number of function arguments, see https://github.com/phpstan/phpstan/issues/8214)
608
+ * @template A2
609
+ * @template A3
610
+ * @template A4
611
+ * @template A5
612
+ * @param callable(A1, A2, A3, A4, A5):(\Generator<mixed, PromiseInterface<TYield>, TYield, PromiseInterface<T>|T>|PromiseInterface<T>|T) $function
596
613
* @param mixed ...$args Optional list of additional arguments that will be passed to the given `$function` as is
597
- * @return PromiseInterface<mixed >
614
+ * @return PromiseInterface<T >
598
615
* @since 3.0.0
599
616
*/
600
617
function coroutine (callable $ function , mixed ...$ args ): PromiseInterface
@@ -611,7 +628,7 @@ function coroutine(callable $function, mixed ...$args): PromiseInterface
611
628
612
629
$ promise = null ;
613
630
$ deferred = new Deferred (function () use (&$ promise ) {
614
- /** @var ?PromiseInterface $promise */
631
+ /** @var ?PromiseInterface<T> $promise */
615
632
if ($ promise instanceof PromiseInterface && \method_exists ($ promise , 'cancel ' )) {
616
633
$ promise ->cancel ();
617
634
}
@@ -632,7 +649,6 @@ function coroutine(callable $function, mixed ...$args): PromiseInterface
632
649
return ;
633
650
}
634
651
635
- /** @var mixed $promise */
636
652
$ promise = $ generator ->current ();
637
653
if (!$ promise instanceof PromiseInterface) {
638
654
$ next = null ;
@@ -642,6 +658,7 @@ function coroutine(callable $function, mixed ...$args): PromiseInterface
642
658
return ;
643
659
}
644
660
661
+ /** @var PromiseInterface<TYield> $promise */
645
662
assert ($ next instanceof \Closure);
646
663
$ promise ->then (function ($ value ) use ($ generator , $ next ) {
647
664
$ generator ->send ($ value );
@@ -660,12 +677,13 @@ function coroutine(callable $function, mixed ...$args): PromiseInterface
660
677
}
661
678
662
679
/**
663
- * @param iterable<callable():PromiseInterface<mixed>> $tasks
664
- * @return PromiseInterface<array<mixed>>
680
+ * @template T
681
+ * @param iterable<callable():(PromiseInterface<T>|T)> $tasks
682
+ * @return PromiseInterface<array<T>>
665
683
*/
666
684
function parallel (iterable $ tasks ): PromiseInterface
667
685
{
668
- /** @var array<int,PromiseInterface> $pending */
686
+ /** @var array<int,PromiseInterface<T> > $pending */
669
687
$ pending = [];
670
688
$ deferred = new Deferred (function () use (&$ pending ) {
671
689
foreach ($ pending as $ promise ) {
@@ -720,14 +738,15 @@ function parallel(iterable $tasks): PromiseInterface
720
738
}
721
739
722
740
/**
723
- * @param iterable<callable():PromiseInterface<mixed>> $tasks
724
- * @return PromiseInterface<array<mixed>>
741
+ * @template T
742
+ * @param iterable<callable():(PromiseInterface<T>|T)> $tasks
743
+ * @return PromiseInterface<array<T>>
725
744
*/
726
745
function series (iterable $ tasks ): PromiseInterface
727
746
{
728
747
$ pending = null ;
729
748
$ deferred = new Deferred (function () use (&$ pending ) {
730
- /** @var ?PromiseInterface $pending */
749
+ /** @var ?PromiseInterface<T> $pending */
731
750
if ($ pending instanceof PromiseInterface && \method_exists ($ pending , 'cancel ' )) {
732
751
$ pending ->cancel ();
733
752
}
@@ -774,14 +793,15 @@ function series(iterable $tasks): PromiseInterface
774
793
}
775
794
776
795
/**
777
- * @param iterable<(callable():PromiseInterface<mixed>)|(callable(mixed):PromiseInterface<mixed>)> $tasks
778
- * @return PromiseInterface<mixed>
796
+ * @template T
797
+ * @param iterable<(callable():(PromiseInterface<T>|T))|(callable(mixed):(PromiseInterface<T>|T))> $tasks
798
+ * @return PromiseInterface<($tasks is non-empty-array|\Traversable ? T : null)>
779
799
*/
780
800
function waterfall (iterable $ tasks ): PromiseInterface
781
801
{
782
802
$ pending = null ;
783
803
$ deferred = new Deferred (function () use (&$ pending ) {
784
- /** @var ?PromiseInterface $pending */
804
+ /** @var ?PromiseInterface<T> $pending */
785
805
if ($ pending instanceof PromiseInterface && \method_exists ($ pending , 'cancel ' )) {
786
806
$ pending ->cancel ();
787
807
}
0 commit comments