Repository: eslint-functional/eslint-plugin-functional
Pull request #866 (2024-08-26 01:33:29)

fix(no-expression-statements): ignore `Promise<void>` when `ignoreVoid` is set

graphite-app[bot]: ## Your org has enabled the Graphite merge queue for merging into main

Add the label “Status: Merge Queue” to the PR and Graphite will automatically add it to the merge queue when it’s ready to merge. Or use the label “Status: Hotfix” to add to the merge queue as a hot fix.

You must have a Graphite account and log in to Graphite in order to use the merge queue. Sign up using [this link](https://app.graphite.dev/invite/github/eslint-functional?ref=merge-queue-instructions-comment&prId=5394154812).
RebeccaStevens: * **#866** <a href="https://app.graphite.dev/github/pr/eslint-functional/eslint-plugin-functional/866?utm_source=stack-comment-icon" target="_blank"><img src="https://static.graphite.dev/graphite-32x32-black.png" alt="Graphite" width="10px" height="10px"/></a> 👈
* `main`

This stack of pull requests is managed by Graphite. <a href="https://stacking.dev/?utm_source=stack-comment">Learn more about stacking.</a>
<h2></h2>

 Join @RebeccaStevens and the rest of your teammates on <a href="https://graphite.dev?utm-source=stack-comment"><img src="https://static.graphite.dev/graphite-32x32-black.png" alt="Graphite" width="11px" height="11px"/> <b>Graphite</b></a>
  <!-- Current dependencies on/for this PR: -->
graphite-app[bot]: ### Merge activity

* **Aug 25, 9:34 PM EDT**: `RebeccaStevens` added this pull request to the [Graphite merge queue](https://app.graphite.dev/merges?org=eslint-functional&repo=eslint-plugin-functional).


Patch:
diff --git a/docs/rules/no-expression-statements.md b/docs/rules/no-expression-statements.md
index 8dfaf81..079b97c 100644
--- a/docs/rules/no-expression-statements.md
+++ b/docs/rules/no-expression-statements.md
@@ -81,7 +81,8 @@ const defaults = {
 
 ### `ignoreVoid`
 
-When enabled, expression of type void are not flagged as violations. This options requires TypeScript in order to work.
+When enabled, expression of type `void` and `Promise<void>` are not flagged as violations.
+This options requires TypeScript in order to work.
 
 ### `ignoreSelfReturning`
 
diff --git a/src/rules/no-expression-statements.ts b/src/rules/no-expression-statements.ts
index c231cde..a68d4c3 100644
--- a/src/rules/no-expression-statements.ts
+++ b/src/rules/no-expression-statements.ts
@@ -5,6 +5,7 @@ import type {
 } from "@typescript-eslint/utils/json-schema";
 import type { RuleContext } from "@typescript-eslint/utils/ts-eslint";
 import { deepmerge } from "deepmerge-ts";
+import type ts from "typescript";
 
 import tsApiUtils from "#/conditional-imports/ts-api-utils";
 import typescript from "#/conditional-imports/typescript";
@@ -21,7 +22,11 @@ import {
   createRule,
   getTypeOfNode,
 } from "#/utils/rule";
-import { isCallExpression, isYieldExpression } from "#/utils/type-guards";
+import {
+  isCallExpression,
+  isPromiseType,
+  isYieldExpression,
+} from "#/utils/type-guards";
 
 /**
  * The name of this rule.
@@ -136,7 +141,16 @@ function checkExpressionStatement(
       };
     }
 
-    if (ignoreVoid && tsApiUtils?.isIntrinsicVoidType(returnType) === true) {
+    if (
+      ignoreVoid &&
+      (tsApiUtils?.isIntrinsicVoidType(returnType) === true ||
+        ("typeArguments" in returnType &&
+          isPromiseType(context, returnType) &&
+          (returnType.typeArguments as ts.Type[]).length > 0 &&
+          tsApiUtils?.isIntrinsicVoidType(
+            (returnType.typeArguments as ts.Type[])[0]!,
+          ) === true))
+    ) {
       return {
         context,
         descriptors: [],


Test patch:
diff --git a/tests/rules/no-expression-statements.test.ts b/tests/rules/no-expression-statements.test.ts
index 0fab658..66677e4 100644
--- a/tests/rules/no-expression-statements.test.ts
+++ b/tests/rules/no-expression-statements.test.ts
@@ -93,6 +93,14 @@ describe(name, () => {
           `,
           options: [{ ignoreVoid: true }],
         });
+
+        valid({
+          code: dedent`
+            function foo() { return Promise.resolve(); }
+            foo();
+          `,
+          options: [{ ignoreVoid: true }],
+        });
       });
 
       it("ignoreSelfReturning", () => {