Skip to content

Commit 05d3135

Browse files
committed
WAP
1 parent 0e7e7a8 commit 05d3135

File tree

5 files changed

+87
-33
lines changed

5 files changed

+87
-33
lines changed

src/FulfilledPromise.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,19 @@
44

55
/**
66
* @deprecated 2.8.0 External usage of FulfilledPromise is deprecated, use `resolve()` instead.
7+
* @template-implements PromiseInterface
8+
* @template-covariant T
79
*/
810
class FulfilledPromise implements ExtendedPromiseInterface, CancellablePromiseInterface
911
{
12+
/**
13+
* @var T
14+
*/
1015
private $value;
1116

17+
/**
18+
* @param T $value
19+
*/
1220
public function __construct($value = null)
1321
{
1422
if ($value instanceof PromiseInterface) {
@@ -18,6 +26,11 @@ public function __construct($value = null)
1826
$this->value = $value;
1927
}
2028

29+
/**
30+
* @template TFulfilled as PromiseInterface<T>|T
31+
* @param (callable(T): TFulfilled)|null $onFulfilled
32+
* @return ($onFulfilled is null ? $this : (TFulfilled is PromiseInterface ? TFulfilled : PromiseInterface<TFulfilled>))
33+
*/
2134
public function then(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null)
2235
{
2336
if (null === $onFulfilled) {

src/Promise.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,17 @@
22

33
namespace React\Promise;
44

5+
/**
6+
* @template-implements PromiseInterface
7+
* @template-covariant T
8+
*/
59
class Promise implements ExtendedPromiseInterface, CancellablePromiseInterface
610
{
711
private $canceller;
12+
13+
/**
14+
* @var PromiseInterface<T>
15+
*/
816
private $result;
917

1018
private $handlers = [];
@@ -25,6 +33,11 @@ public function __construct(callable $resolver, callable $canceller = null)
2533
$this->call($cb);
2634
}
2735

36+
/**
37+
* @template TFulfilled as PromiseInterface<T>|T
38+
* @param (callable(T): TFulfilled)|null $onFulfilled
39+
* @return ($onFulfilled is null ? $this : (TFulfilled is PromiseInterface ? TFulfilled : PromiseInterface<TFulfilled>))
40+
*/
2841
public function then(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null)
2942
{
3043
if (null !== $this->result) {

src/PromiseInterface.php

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
/**
66
* @template-covariant T
7-
* @template-covariant R
87
*/
98
interface PromiseInterface
109
{
@@ -37,10 +36,8 @@ interface PromiseInterface
3736
* 3. `$onProgress` (deprecated) may be called multiple times.
3837
*
3938
* @template TFulfilled as PromiseInterface<T>|T
40-
* @template TRejected as \Throwable
41-
* @param callable(T): TFulfilled $onFulfilled
42-
* @param callable(R): TRejected $onRejected
43-
* @return (TFulfilled is PromiseInterface ? TFulfilled : PromiseInterface<TFulfilled, TRejected>)
39+
* @param (callable(T): TFulfilled)|null $onFulfilled
40+
* @return ($onFulfilled is null ? $this : (TFulfilled is PromiseInterface ? TFulfilled : PromiseInterface<TFulfilled>))
4441
*/
4542
public function then(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null);
4643
}

src/functions.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@
1313
*
1414
* If `$promiseOrValue` is a promise, it will be returned as is.
1515
*
16-
* @template T
17-
* @param T $promiseOrValue
18-
* @return (T is PromiseInterface ? T : PromiseInterface<T>)
16+
* @template-covariant T
17+
* @template TFulfilled as PromiseInterface<T>|T
18+
* @param TFulfilled $promiseOrValue
19+
* @return (TFulfilled is PromiseInterface ? TFulfilled : PromiseInterface<TFulfilled>)
1920
*/
2021
function resolve($promiseOrValue = null)
2122
{
@@ -56,7 +57,7 @@ function resolve($promiseOrValue = null)
5657
* @template T is null
5758
* @template R
5859
* @param R $promiseOrValue
59-
* @return (R is PromiseInterface ? R : PromiseInterface<T, R>)
60+
* @return PromiseInterface<T>
6061
*/
6162
function reject($promiseOrValue = null)
6263
{
@@ -133,7 +134,7 @@ function race($promisesOrValues)
133134
*
134135
* @template T
135136
* @param array<PromiseInterface<T>|T> $promisesOrValues
136-
* @return PromiseInterface<array<T>>
137+
* @return PromiseInterface<T>
137138
*/
138139
function any($promisesOrValues)
139140
{

types/Promises.php

Lines changed: 53 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use function PHPStan\Testing\assertType;
88
use function React\Promise\all;
9+
use function React\Promise\any;
910
use function React\Promise\race;
1011
use function React\Promise\reject;
1112
use function React\Promise\resolve;
@@ -14,34 +15,63 @@
1415
$passThroughThrowable = static function (Throwable $t): PromiseInterface {
1516
return reject($t);
1617
};
17-
$stringOrInt = function (): string|int {
18+
$stringOrInt = function (): int|string {
1819
return time() % 2 ? 'string' : time();
1920
};
2021
$tosseable = new Exception('Oops I did it again!');
2122

23+
/**
24+
* basic
25+
*/
2226
assertType('React\Promise\PromiseInterface<bool>', resolve(true));
23-
//assertType('React\Promise\PromiseInterface<string|int>', resolve($stringOrInt()));
2427
assertType('React\Promise\PromiseInterface<int|string>', resolve($stringOrInt()));
2528
assertType('React\Promise\PromiseInterface<bool>', resolve(resolve(true)));
26-
//assertType('React\Promise\PromiseInterface<array<bool>>', all([resolve(true), resolve(false)]));
27-
//assertType('React\Promise\PromiseInterface<array<bool>>', all([resolve(true), false]));
28-
//assertType('React\Promise\PromiseInterface<array<bool|int>>', all([resolve(true), resolve(time())]));
29-
//assertType('React\Promise\PromiseInterface<array<bool|float>>', all([resolve(true), hrtime()]));
30-
//assertType('React\Promise\PromiseInterface<array<bool|int>>', all([true, resolve(time())]));
31-
//assertType('React\Promise\PromiseInterface<bool>', race([resolve(true), resolve(true)]));
32-
//assertType('React\Promise\PromiseInterface<bool>', resolve(true)->then($passThroughBoolFn));
33-
//assertType('React\Promise\PromiseInterface<bool>', resolve(true)->then()->then($passThroughBoolFn));
34-
//assertType('React\Promise\PromiseInterface<bool>', resolve(true)->then(null)->then($passThroughBoolFn));
35-
//assertType('React\Promise\PromiseInterface<bool>', resolve(true)->then($passThroughBoolFn)->then($passThroughBoolFn));
36-
//assertType('React\Promise\PromiseInterface<bool>', resolve(true)->then($passThroughBoolFn, $passThroughThrowable)->then($passThroughBoolFn));
29+
30+
/**
31+
* chaining
32+
*/
33+
assertType('React\Promise\PromiseInterface<bool>', resolve(true)->then($passThroughBoolFn));
34+
assertType('React\Promise\PromiseInterface<bool>', resolve(true)->then()->then($passThroughBoolFn));
35+
assertType('React\Promise\PromiseInterface<bool>', resolve(true)->then(null)->then($passThroughBoolFn));
36+
assertType('React\Promise\PromiseInterface<bool>', resolve(true)->then($passThroughBoolFn)->then($passThroughBoolFn));
37+
assertType('React\Promise\PromiseInterface<bool>', resolve(true)->then($passThroughBoolFn, $passThroughThrowable)->then($passThroughBoolFn));
3738
assertType('React\Promise\PromiseInterface<bool>', resolve(true)->then(null, $passThroughThrowable)->then($passThroughBoolFn));
38-
//assertType('React\Promise\PromiseInterface<bool>', resolve(true)->then()->then(null, $passThroughThrowable)->then($passThroughBoolFn));
39-
//assertType('React\Promise\FulfilledPromise<bool>', new FulfilledPromise(true));
40-
//assertType('React\Promise\PromiseInterface<bool>', (new FulfilledPromise(true))->then($passThroughBoolFn));
41-
42-
//assertType('React\Promise\PromiseInterface<null, Exception>', reject($tosseable));
43-
//assertType('React\Promise\PromiseInterface<null, Throwable>', reject($tosseable));
44-
//assertType('React\Promise\PromiseInterface<null, Throwable>', reject($tosseable)->then($passThroughBoolFn, $passThroughThrowable));
45-
//assertType('React\Promise\PromiseInterface<null, Throwable>', reject($tosseable)->then()->then($passThroughBoolFn, $passThroughThrowable));
46-
//assertType('React\Promise\PromiseInterface<null, Throwable>', reject($tosseable)->then(null, $passThroughThrowable));
47-
//assertType('React\Promise\PromiseInterface<null, Throwable>', reject($tosseable)->then()->then(null, $passThroughThrowable));
39+
assertType('React\Promise\PromiseInterface<bool>', resolve(true)->then()->then(null, $passThroughThrowable)->then($passThroughBoolFn));
40+
41+
/**
42+
* all
43+
*/
44+
assertType('React\Promise\PromiseInterface<array<bool>>', all([resolve(true), resolve(false)]));
45+
assertType('React\Promise\PromiseInterface<array<bool>>', all([resolve(true), false]));
46+
assertType('React\Promise\PromiseInterface<array<bool|int>>', all([resolve(true), resolve(time())]));
47+
assertType('React\Promise\PromiseInterface<array<bool|float>>', all([resolve(true), hrtime()]));
48+
assertType('React\Promise\PromiseInterface<array<bool|int>>', all([true, resolve(time())]));
49+
50+
/**
51+
* any
52+
*/
53+
assertType('React\Promise\PromiseInterface<bool>', any([resolve(true), resolve(false)]));
54+
assertType('React\Promise\PromiseInterface<bool>', any([resolve(true), false]));
55+
assertType('React\Promise\PromiseInterface<bool|int>', any([resolve(true), resolve(time())]));
56+
assertType('React\Promise\PromiseInterface<bool|float>', any([resolve(true), hrtime()]));
57+
assertType('React\Promise\PromiseInterface<bool|int>', any([true, resolve(time())]));
58+
59+
/**
60+
* race
61+
*/
62+
assertType('React\Promise\PromiseInterface<bool>', race([resolve(true), resolve(false)]));
63+
assertType('React\Promise\PromiseInterface<bool>', race([resolve(true), false]));
64+
assertType('React\Promise\PromiseInterface<bool|int>', race([resolve(true), resolve(time())]));
65+
assertType('React\Promise\PromiseInterface<bool|float>', race([resolve(true), hrtime()]));
66+
assertType('React\Promise\PromiseInterface<bool|int>', race([true, resolve(time())]));
67+
68+
/**
69+
* race
70+
*/
71+
assertType('React\Promise\PromiseInterface<bool>', race([resolve(true), resolve(true)]));
72+
73+
/**
74+
* direct class access (deprecated!!!)
75+
*/
76+
assertType('React\Promise\FulfilledPromise<bool>', new FulfilledPromise(true));
77+
assertType('React\Promise\PromiseInterface<bool>', (new FulfilledPromise(true))->then($passThroughBoolFn));

0 commit comments

Comments
 (0)