diff --git a/psalm-baseline.xml b/psalm-baseline.xml
index 15b8b53fb..007e150b9 100644
--- a/psalm-baseline.xml
+++ b/psalm-baseline.xml
@@ -1592,6 +1592,7 @@
]]>
]]>
]]>
+ ]]>
]]>
diff --git a/resources/.phpstorm.meta.php b/resources/.phpstorm.meta.php/.phpstorm.meta.php
similarity index 100%
rename from resources/.phpstorm.meta.php
rename to resources/.phpstorm.meta.php/.phpstorm.meta.php
diff --git a/resources/.phpstorm.meta.php/PromiseInterface.php b/resources/.phpstorm.meta.php/PromiseInterface.php
new file mode 100644
index 000000000..74e48c254
--- /dev/null
+++ b/resources/.phpstorm.meta.php/PromiseInterface.php
@@ -0,0 +1,50 @@
+|TFulfilled)) $onFulfilled
+ * @param ?(callable(\Throwable): (PromiseInterface|TRejected)) $onRejected
+ * @return PromiseInterface<($onRejected is null ? ($onFulfilled is null ? T : TFulfilled) : ($onFulfilled is null ? T|TRejected : TFulfilled|TRejected))>
+ */
+ public function then(?callable $onFulfilled = null, ?callable $onRejected = null, ?callable $onProgress = null);
+}
diff --git a/src/Internal/Workflow/WorkflowContext.php b/src/Internal/Workflow/WorkflowContext.php
index 64a6267ab..f1e2a85d8 100644
--- a/src/Internal/Workflow/WorkflowContext.php
+++ b/src/Internal/Workflow/WorkflowContext.php
@@ -183,13 +183,9 @@ public function getLastCompletionResultValues(): ?ValuesInterface
return $this->lastCompletionResult;
}
- public function getLastCompletionResult($type = null)
+ public function getLastCompletionResult(mixed $type = null): mixed
{
- if ($this->lastCompletionResult === null) {
- return null;
- }
-
- return $this->lastCompletionResult->getValue(0, $type);
+ return $this->lastCompletionResult?->getValue(0, $type);
}
public function getClient(): ClientInterface
diff --git a/src/Workflow.php b/src/Workflow.php
index fa47e0fee..cc5f244c2 100644
--- a/src/Workflow.php
+++ b/src/Workflow.php
@@ -183,6 +183,10 @@ public static function getInput(): ValuesInterface
* You can see more information about the capabilities of the child
* asynchronous task in {@see CancellationScopeInterface} interface.
*
+ * @template TReturn
+ * @param callable(): (TReturn|\Generator) $task
+ * @return CancellationScopeInterface
+ *
* @throws OutOfContextException in the absence of the workflow execution context.
*/
public static function async(callable $task): CancellationScopeInterface
@@ -231,6 +235,10 @@ public static function async(callable $task): CancellationScopeInterface
*
* Use asyncDetached to handle cleanup and compensation logic.
*
+ * @template TReturn
+ * @param callable(): (TReturn|\Generator) $task
+ * @return CancellationScopeInterface
+ *
* @throws OutOfContextException in the absence of the workflow execution context.
*/
public static function asyncDetached(callable $task): CancellationScopeInterface
@@ -315,10 +323,9 @@ public static function awaitWithTimeout($interval, callable|Mutex|PromiseInterfa
* Returns value of last completion result, if any.
*
* @param Type|TypeEnum|mixed $type
- * @return mixed
* @throws OutOfContextException in the absence of the workflow execution context.
*/
- public static function getLastCompletionResult($type = null)
+ public static function getLastCompletionResult($type = null): mixed
{
return self::getCurrentContext()->getLastCompletionResult($type);
}
@@ -685,7 +692,10 @@ public static function newContinueAsNewStub(string $class, ?ContinueAsNewOptions
* }
* ```
*
+ * @param non-empty-string $type
+ * @param list $args
* @param Type|string|\ReflectionType|\ReflectionClass|null $returnType
+ * @return PromiseInterface
*
* @throws OutOfContextException in the absence of the workflow execution context.
*/
@@ -879,6 +889,7 @@ public static function newUntypedExternalWorkflowStub(WorkflowExecution $executi
* }
* ```
*
+ * @param non-empty-string $type
* @param ActivityOptions|null $options
* @return PromiseInterface
* @throws OutOfContextException in the absence of the workflow execution context.
diff --git a/src/Workflow/CancellationScopeInterface.php b/src/Workflow/CancellationScopeInterface.php
index 8a819c2a0..fd38ec2b4 100644
--- a/src/Workflow/CancellationScopeInterface.php
+++ b/src/Workflow/CancellationScopeInterface.php
@@ -14,7 +14,7 @@
use React\Promise\PromiseInterface;
/**
- * @template T
+ * @template-covariant T
* @yield T
* @extends PromiseInterface
*/
diff --git a/src/Workflow/ScopedContextInterface.php b/src/Workflow/ScopedContextInterface.php
index 714418a6f..a7b2667da 100644
--- a/src/Workflow/ScopedContextInterface.php
+++ b/src/Workflow/ScopedContextInterface.php
@@ -21,6 +21,10 @@ interface ScopedContextInterface extends WorkflowContextInterface
/**
* The method calls an asynchronous task and returns a promise.
*
+ * @template TReturn
+ * @param callable(): (TReturn|\Generator) $handler
+ * @return CancellationScopeInterface
+ *
* @see Workflow::async()
*/
public function async(callable $handler): CancellationScopeInterface;
@@ -29,6 +33,10 @@ public function async(callable $handler): CancellationScopeInterface;
* Cancellation scope which does not react to parent cancel and completes
* in background.
*
+ * @template TReturn
+ * @param callable(): (TReturn|\Generator) $handler
+ * @return CancellationScopeInterface
+ *
* @see Workflow::asyncDetached()
*/
public function asyncDetached(callable $handler): CancellationScopeInterface;
diff --git a/src/Workflow/WorkflowContextInterface.php b/src/Workflow/WorkflowContextInterface.php
index f011ea02f..495bf82bf 100644
--- a/src/Workflow/WorkflowContextInterface.php
+++ b/src/Workflow/WorkflowContextInterface.php
@@ -49,9 +49,8 @@ public function getInput(): ValuesInterface;
* @see Workflow::getLastCompletionResult()
*
* @param Type|string|null $type
- * @return mixed
*/
- public function getLastCompletionResult($type = null);
+ public function getLastCompletionResult(mixed $type = null): mixed;
/**
* A method that allows you to dynamically register additional query
diff --git a/tests/Acceptance/Extra/Versioning/VersioningTest.php b/tests/Acceptance/Extra/Versioning/VersioningTest.php
index bc8250d96..9ba4815a1 100644
--- a/tests/Acceptance/Extra/Versioning/VersioningTest.php
+++ b/tests/Acceptance/Extra/Versioning/VersioningTest.php
@@ -44,7 +44,7 @@ public function handle()
$version = yield Workflow::getVersion('test', Workflow::DEFAULT_VERSION, 2);
if ($version === 1) {
- yield Workflow::sideEffect(static fn() => 'test');
+ yield Workflow::sideEffect(static fn(): string => 'test');
return 'v1';
}
diff --git a/tests/Fixtures/src/Workflow/SideEffectWorkflow.php b/tests/Fixtures/src/Workflow/SideEffectWorkflow.php
index f986e622f..3f8474d4e 100644
--- a/tests/Fixtures/src/Workflow/SideEffectWorkflow.php
+++ b/tests/Fixtures/src/Workflow/SideEffectWorkflow.php
@@ -12,7 +12,6 @@
namespace Temporal\Tests\Workflow;
use Temporal\Activity\ActivityOptions;
-use Temporal\Common\Uuid;
use Temporal\Workflow;
use Temporal\Workflow\WorkflowMethod;
use Temporal\Tests\Activity\SimpleActivity;
@@ -25,13 +24,13 @@ public function handler(string $input): iterable
{
$simple = Workflow::newActivityStub(
SimpleActivity::class,
- ActivityOptions::new()->withStartToCloseTimeout(5)
+ ActivityOptions::new()->withStartToCloseTimeout(5),
);
$result = yield Workflow::sideEffect(
- function () use ($input) {
+ static function () use ($input): string {
return $input . '-42';
- }
+ },
);
return yield $simple->lower($result);