diff --git a/packages/eslint-plugin/docs/rules/no-floating-promises.md b/packages/eslint-plugin/docs/rules/no-floating-promises.md index ffaa542f3f11..4ea2e6addc99 100644 --- a/packages/eslint-plugin/docs/rules/no-floating-promises.md +++ b/packages/eslint-plugin/docs/rules/no-floating-promises.md @@ -51,6 +51,8 @@ The rule accepts an options object with the following properties: type Options = { // if true, checking void expressions will be skipped ignoreVoid?: boolean; + // if true, checking for async iife will be skipped + ignoreIIFE?: boolean; }; const defaults = { @@ -60,7 +62,8 @@ const defaults = { ### `ignoreVoid` -This allows to easily suppress false-positives with void operator. +This allows you to stop the rule reporting promises consumed with void operator. +This can be a good way to explicitly mark a promise as intentionally not awaited. Examples of **correct** code for this rule with `{ ignoreVoid: true }`: @@ -73,10 +76,25 @@ void returnsPromise(); void Promise.reject('value'); ``` +### `ignoreIIFE` + +This allows you to skip checking of async iife + +Examples of **correct** code for this rule with `{ ignoreIIFE: true }`: + +```ts +await(async function() { + await res(1); +})(); + +(async function() { + await res(1); +})(); +``` + ## When Not To Use It -If you do not use Promise-like values in your codebase or want to allow them to -remain unhandled. +If you do not use Promise-like values in your codebase, or want to allow them to remain unhandled. ## Related to diff --git a/packages/eslint-plugin/src/rules/no-floating-promises.ts b/packages/eslint-plugin/src/rules/no-floating-promises.ts index c3ee7ffccf3c..09d70bac42c0 100644 --- a/packages/eslint-plugin/src/rules/no-floating-promises.ts +++ b/packages/eslint-plugin/src/rules/no-floating-promises.ts @@ -1,12 +1,17 @@ import * as tsutils from 'tsutils'; import * as ts from 'typescript'; -import { TSESLint } from '@typescript-eslint/experimental-utils'; +import { + TSESLint, + AST_NODE_TYPES, + TSESTree, +} from '@typescript-eslint/experimental-utils'; import * as util from '../util'; type Options = [ { ignoreVoid?: boolean; + ignoreIIFE?: boolean; }, ]; @@ -33,6 +38,7 @@ export default util.createRule({ type: 'object', properties: { ignoreVoid: { type: 'boolean' }, + ignoreIIFE: { type: 'boolean' }, }, additionalProperties: false, }, @@ -42,6 +48,7 @@ export default util.createRule({ defaultOptions: [ { ignoreVoid: false, + ignoreIIFE: false, }, ], @@ -54,6 +61,10 @@ export default util.createRule({ ExpressionStatement(node): void { const { expression } = parserServices.esTreeNodeToTSNodeMap.get(node); + if (options.ignoreIIFE && isAsyncIife(node)) { + return; + } + if (isUnhandledPromise(checker, expression)) { if (options.ignoreVoid) { context.report({ @@ -80,6 +91,19 @@ export default util.createRule({ }, }; + function isAsyncIife(node: TSESTree.ExpressionStatement): boolean { + if (node.expression.type !== AST_NODE_TYPES.CallExpression) { + return false; + } + + return ( + node.expression.type === AST_NODE_TYPES.CallExpression && + (node.expression.callee.type === + AST_NODE_TYPES.ArrowFunctionExpression || + node.expression.callee.type === AST_NODE_TYPES.FunctionExpression) + ); + } + function isUnhandledPromise( checker: ts.TypeChecker, node: ts.Node, diff --git a/packages/eslint-plugin/tests/rules/no-floating-promises.test.ts b/packages/eslint-plugin/tests/rules/no-floating-promises.test.ts index c7e688c9852e..f6601a0613a1 100644 --- a/packages/eslint-plugin/tests/rules/no-floating-promises.test.ts +++ b/packages/eslint-plugin/tests/rules/no-floating-promises.test.ts @@ -335,6 +335,54 @@ async function test() { return returnsPromise(); } `, + // ignoreIIFE + { + code: ` + (async () => { + await something(); + })(); + `, + options: [{ ignoreIIFE: true }], + }, + { + code: ` + (async () => { + something(); + })(); + `, + options: [{ ignoreIIFE: true }], + }, + { + code: '(async function foo() {})();', + options: [{ ignoreIIFE: true }], + }, + { + code: ` + function foo() { + (async function bar() {})(); + } + `, + options: [{ ignoreIIFE: true }], + }, + { + code: ` + const foo = () => + new Promise(res => { + (async function() { + await res(1); + })(); + }); + `, + options: [{ ignoreIIFE: true }], + }, + { + code: ` + (async function() { + await res(1); + })(); + `, + options: [{ ignoreIIFE: true }], + }, ], invalid: [ @@ -726,5 +774,126 @@ async function test() { }, ], }, + { + code: ` + (async () => { + await something(); + })(); + `, + errors: [ + { + line: 2, + messageId: 'floating', + }, + ], + }, + { + code: ` + (async () => { + something(); + })(); + `, + errors: [ + { + line: 2, + messageId: 'floating', + }, + ], + }, + { + code: '(async function foo() {})();', + errors: [ + { + line: 1, + messageId: 'floating', + }, + ], + }, + { + code: ` + function foo() { + (async function bar() {})(); + } + `, + errors: [ + { + line: 3, + messageId: 'floating', + }, + ], + }, + { + code: ` + const foo = () => + new Promise(res => { + (async function() { + await res(1); + })(); + }); + `, + errors: [ + { + line: 4, + messageId: 'floating', + }, + ], + }, + { + code: ` + (async function() { + await res(1); + })(); + `, + errors: [ + { + line: 2, + messageId: 'floating', + }, + ], + }, + { + code: ` + (async function() { + Promise.resolve(); + })(); + `, + options: [{ ignoreIIFE: true }], + errors: [ + { + line: 3, + messageId: 'floating', + }, + ], + }, + { + code: ` + (async function() { + const promiseIntersection: Promise & number; + promiseIntersection; + promiseIntersection.then(() => {}); + promiseIntersection.catch(); + promiseIntersection.finally(); + })(); + `, + options: [{ ignoreIIFE: true }], + errors: [ + { + line: 4, + messageId: 'floating', + }, + { + line: 5, + messageId: 'floating', + }, + { + line: 6, + messageId: 'floating', + }, + { + line: 7, + messageId: 'floating', + }, + ], + }, ], }); diff --git a/packages/typescript-estree/src/ts-estree/ts-estree.ts b/packages/typescript-estree/src/ts-estree/ts-estree.ts index 5792ebc02058..1781ffd5fff1 100644 --- a/packages/typescript-estree/src/ts-estree/ts-estree.ts +++ b/packages/typescript-estree/src/ts-estree/ts-estree.ts @@ -392,7 +392,8 @@ export type LeftHandSideExpression = | PrimaryExpression | TaggedTemplateExpression | TSNonNullExpression - | TSAsExpression; + | TSAsExpression + | ArrowFunctionExpression; export type Literal = | BooleanLiteral | NumberLiteral pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy