Skip to content

Commit

Permalink
fix(eslint-plugin): [require-await] Allow concise arrow function bodi…
Browse files Browse the repository at this point in the history
…es (#826)
  • Loading branch information
scottohara authored and bradzacher committed Aug 21, 2019
1 parent 6a30de2 commit 29fddfd
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 6 deletions.
26 changes: 22 additions & 4 deletions packages/eslint-plugin/src/rules/require-await.ts
Expand Up @@ -64,6 +64,15 @@ export default util.createRule<Options, MessageIds>({

case AST_NODE_TYPES.ArrowFunctionExpression:
rules.ArrowFunctionExpression(node);

// If body type is not BlockStatment, we need to check the return type here
if (node.body.type !== AST_NODE_TYPES.BlockStatement) {
const expression = parserServices.esTreeNodeToTSNodeMap.get(
node.body,
);
scopeInfo.returnsPromise = isThenableType(expression);
}

break;
}
}
Expand Down Expand Up @@ -102,6 +111,18 @@ export default util.createRule<Options, MessageIds>({
}
}

/**
* Checks if the node returns a thenable type
*
* @param {ASTNode} node - The node to check
* @returns {boolean}
*/
function isThenableType(node: ts.Node) {
const type = checker.getTypeAtLocation(node);

return tsutils.isThenableType(checker, node, type);
}

return {
'FunctionDeclaration[async = true]': enterFunction,
'FunctionExpression[async = true]': enterFunction,
Expand All @@ -122,10 +143,7 @@ export default util.createRule<Options, MessageIds>({
return;
}

const type = checker.getTypeAtLocation(expression);
if (tsutils.isThenableType(checker, expression, type)) {
scopeInfo.returnsPromise = true;
}
scopeInfo.returnsPromise = isThenableType(expression);
},

AwaitExpression: rules.AwaitExpression as TSESLint.RuleFunction<
Expand Down
42 changes: 40 additions & 2 deletions packages/eslint-plugin/tests/rules/require-await.test.ts
Expand Up @@ -41,9 +41,15 @@ ruleTester.run('require-await', rule, {
}`,
},
{
// Non-async arrow function expression
// Non-async arrow function expression (concise-body)
code: `const numberOne = (): number => 1;`,
},
{
// Non-async arrow function expression (block-body)
code: `const numberOne = (): number => {
return 1;
};`,
},
{
// Async function declaration with await
code: `async function numberOne(): Promise<number> {
Expand All @@ -57,9 +63,15 @@ ruleTester.run('require-await', rule, {
}`,
},
{
// Async arrow function expression with await
// Async arrow function expression with await (concise-body)
code: `const numberOne = async (): Promise<number> => await 1;`,
},
{
// Async arrow function expression with await (block-body)
code: `const numberOne = async (): Promise<number> => {
return await 1;
};`,
},
{
// Async function declaration with promise return
code: `async function numberOne(): Promise<number> {
Expand All @@ -72,6 +84,16 @@ ruleTester.run('require-await', rule, {
return Promise.resolve(1);
}`,
},
{
// Async arrow function with promise return (concise-body)
code: `const numberOne = async (): Promise<number> => Promise.resolve(1);`,
},
{
// Async arrow function with promise return (block-body)
code: `const numberOne = async (): Promise<number> => {
return Promise.resolve(1);
};`,
},
{
// Async function declaration with async function return
code: `async function numberOne(): Promise<number> {
Expand All @@ -90,6 +112,22 @@ ruleTester.run('require-await', rule, {
return Promise.resolve(x);
}`,
},
{
// Async arrow function with async function return (concise-body)
code: `const numberOne = async (): Promise<number> => getAsyncNumber(1);
const getAsyncNumber = async function(x: number): Promise<number> {
return Promise.resolve(x);
}`,
},
{
// Async arrow function with async function return (block-body)
code: `const numberOne = async (): Promise<number> => {
return getAsyncNumber(1);
};
const getAsyncNumber = async function(x: number): Promise<number> {
return Promise.resolve(x);
}`,
},
],

invalid: [
Expand Down

0 comments on commit 29fddfd

Please sign in to comment.