diff --git a/packages/eslint-plugin/src/rules/return-await.ts b/packages/eslint-plugin/src/rules/return-await.ts index 173596e451f..2c47272cdaf 100644 --- a/packages/eslint-plugin/src/rules/return-await.ts +++ b/packages/eslint-plugin/src/rules/return-await.ts @@ -7,6 +7,15 @@ import * as tsutils from 'tsutils'; import * as ts from 'typescript'; import * as util from '../util'; +interface ScopeInfo { + hasAsync: boolean; +} + +type FunctionNode = + | TSESTree.FunctionDeclaration + | TSESTree.FunctionExpression + | TSESTree.ArrowFunctionExpression; + export default util.createRule({ name: 'return-await', meta: { @@ -40,6 +49,14 @@ export default util.createRule({ const checker = parserServices.program.getTypeChecker(); const sourceCode = context.getSourceCode(); + let scopeInfo: ScopeInfo | null = null; + + function enterFunction(node: FunctionNode): void { + scopeInfo = { + hasAsync: node.async, + }; + } + function inTryCatch(node: ts.Node): boolean { let ancestor = node.parent; @@ -185,6 +202,10 @@ export default util.createRule({ } return { + FunctionDeclaration: enterFunction, + FunctionExpression: enterFunction, + ArrowFunctionExpression: enterFunction, + 'ArrowFunctionExpression[async = true]:exit'( node: TSESTree.ArrowFunctionExpression, ): void { @@ -197,6 +218,10 @@ export default util.createRule({ } }, ReturnStatement(node): void { + if (!scopeInfo || !scopeInfo.hasAsync) { + return; + } + const originalNode = parserServices.esTreeNodeToTSNodeMap.get(node); const { expression } = originalNode; diff --git a/packages/eslint-plugin/tests/rules/return-await.test.ts b/packages/eslint-plugin/tests/rules/return-await.test.ts index 94c2c398733..f3e4169ad9d 100644 --- a/packages/eslint-plugin/tests/rules/return-await.test.ts +++ b/packages/eslint-plugin/tests/rules/return-await.test.ts @@ -180,6 +180,20 @@ ruleTester.run('return-await', rule, { } `, }, + { + options: ['always'], + code: ` + declare function foo(): Promise; + + function bar(baz: boolean): Promise | boolean { + if (baz) { + return true; + } else { + return foo(); + } + } + `, + }, { code: ` async function test(): Promise {