From 8ae40afe638671943b4af413ee402cf0970a3faf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandru=20P=C4=83tr=C4=83nescu?= Date: Sat, 22 Feb 2025 16:58:13 +0200 Subject: [PATCH 1/2] Add template support for promise interface --- src/PromiseInterface.php | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/PromiseInterface.php b/src/PromiseInterface.php index c11721e..ed62bb3 100644 --- a/src/PromiseInterface.php +++ b/src/PromiseInterface.php @@ -12,6 +12,7 @@ * the reason why the promise cannot be fulfilled. * * @see https://promisesaplus.com/ + * @template T */ interface PromiseInterface { @@ -23,8 +24,12 @@ interface PromiseInterface * Appends fulfillment and rejection handlers to the promise, and returns * a new promise resolving to the return value of the called handler. * - * @param callable $onFulfilled Invoked when the promise fulfills. - * @param callable $onRejected Invoked when the promise is rejected. + * @template U + * @template V + * @param null|callable(T): U $onFulfilled Invoked when the promise fulfills. + * @param null|callable(mixed): V $onRejected Invoked when the promise is rejected. + * + * @return ($onFulfilled is null ? ($onRejected is null ? PromiseInterface : PromiseInterface) : ($onRejected is null ? PromiseInterface : PromiseInterface)) */ public function then( ?callable $onFulfilled = null, @@ -37,7 +42,10 @@ public function then( * or to its original fulfillment value if the promise is instead * fulfilled. * - * @param callable $onRejected Invoked when the promise is rejected. + * @template V + * @param callable(mixed): V $onRejected Invoked when the promise is rejected. + * + * @return PromiseInterface */ public function otherwise(callable $onRejected): PromiseInterface; @@ -46,13 +54,15 @@ public function otherwise(callable $onRejected): PromiseInterface; * * The three states can be checked against the constants defined on * PromiseInterface: PENDING, FULFILLED, and REJECTED. + * + * @return 'pending'|'fulfilled'|'rejected' */ public function getState(): string; /** * Resolve the promise with the given value. * - * @param mixed $value + * @param T $value * * @throws \RuntimeException if the promise is already resolved. */ @@ -82,7 +92,9 @@ public function cancel(): void; * * If the promise cannot be waited on, then the promise will be rejected. * - * @return mixed + * @param bool $unwrap + * + * @return ($unwrap is true ? T : void) * * @throws \LogicException if the promise has no wait function or if the * promise does not settle after waiting. From b3589779d4e98f2a71e6547d4c3277bec11694bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandru=20P=C4=83tr=C4=83nescu?= Date: Wed, 14 May 2025 13:42:14 +0300 Subject: [PATCH 2/2] Add template support for classes implementing promise interface --- src/Coroutine.php | 2 ++ src/FulfilledPromise.php | 5 ++++- src/Promise.php | 2 ++ src/RejectedPromise.php | 2 ++ 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Coroutine.php b/src/Coroutine.php index 0da0228..0f49829 100644 --- a/src/Coroutine.php +++ b/src/Coroutine.php @@ -42,6 +42,8 @@ * @return Promise * * @see https://github.com/petkaantonov/bluebird/blob/master/API.md#generators inspiration + * @template T + * @template-implements PromiseInterface */ final class Coroutine implements PromiseInterface { diff --git a/src/FulfilledPromise.php b/src/FulfilledPromise.php index 727ec31..3197b23 100644 --- a/src/FulfilledPromise.php +++ b/src/FulfilledPromise.php @@ -10,6 +10,9 @@ * Thenning off of this promise will invoke the onFulfilled callback * immediately and ignore other callbacks. * + * @template T + * @template-implements PromiseInterface + * * @final */ class FulfilledPromise implements PromiseInterface @@ -17,7 +20,7 @@ class FulfilledPromise implements PromiseInterface private $value; /** - * @param mixed $value + * @param T $value */ public function __construct($value) { diff --git a/src/Promise.php b/src/Promise.php index c0c5be2..d0f299d 100644 --- a/src/Promise.php +++ b/src/Promise.php @@ -8,6 +8,8 @@ * Promises/A+ implementation that avoids recursion when possible. * * @see https://promisesaplus.com/ + * @template T + * @template-implements PromiseInterface * * @final */ diff --git a/src/RejectedPromise.php b/src/RejectedPromise.php index 1ebf0b2..36853cc 100644 --- a/src/RejectedPromise.php +++ b/src/RejectedPromise.php @@ -10,6 +10,8 @@ * Thenning off of this promise will invoke the onRejected callback * immediately and ignore other callbacks. * + * @template-implements PromiseInterface + * * @final */ class RejectedPromise implements PromiseInterface