diff --git a/src/rules/requireReturnType.js b/src/rules/requireReturnType.js index be70988c..450647f3 100644 --- a/src/rules/requireReturnType.js +++ b/src/rules/requireReturnType.js @@ -59,8 +59,14 @@ const create = (context) => { const getIsReturnTypeAnnotationUndefined = (targetNode) => { const isReturnTypeAnnotationLiteralUndefined = _.get(targetNode, 'functionNode.returnType.typeAnnotation.id.name') === 'undefined' && _.get(targetNode, 'functionNode.returnType.typeAnnotation.type') === 'GenericTypeAnnotation'; const isReturnTypeAnnotationVoid = _.get(targetNode, 'functionNode.returnType.typeAnnotation.type') === 'VoidTypeAnnotation'; - - return isReturnTypeAnnotationLiteralUndefined || isReturnTypeAnnotationVoid; + const isAsyncReturnTypeAnnotationVoid = _.get(targetNode, 'functionNode.async') && + _.get(targetNode, 'functionNode.returnType.typeAnnotation.id.name') === 'Promise' && ( + _.get(targetNode, 'functionNode.returnType.typeAnnotation.typeParameters.params[0].type') === 'VoidTypeAnnotation' || + _.get(targetNode, 'functionNode.returnType.typeAnnotation.typeParameters.params[0].id.name') === 'undefined' && + _.get(targetNode, 'functionNode.returnType.typeAnnotation.typeParameters.params[0].type') === 'GenericTypeAnnotation' + ); + + return isReturnTypeAnnotationLiteralUndefined || isReturnTypeAnnotationVoid || isAsyncReturnTypeAnnotationVoid; }; const shouldFilterNode = (functionNode) => { @@ -102,8 +108,7 @@ const create = (context) => { const isArrow = functionNode.type === 'ArrowFunctionExpression'; const isArrowFunctionExpression = functionNode.expression; - const hasImplicitReturnType = functionNode.async || functionNode.generator; - const isFunctionReturnUndefined = !isArrowFunctionExpression && !hasImplicitReturnType && (!targetNode.returnStatementNode || isUndefinedReturnType(targetNode.returnStatementNode)); + const isFunctionReturnUndefined = !isArrowFunctionExpression && !(functionNode.generator && !functionNode.async) && (!targetNode.returnStatementNode || isUndefinedReturnType(targetNode.returnStatementNode)); const isReturnTypeAnnotationUndefined = getIsReturnTypeAnnotationUndefined(targetNode); if (skipArrows === 'expressionsOnly' && isArrowFunctionExpression || skipArrows === true && isArrow) { diff --git a/tests/rules/assertions/requireReturnType.js b/tests/rules/assertions/requireReturnType.js index 07e2bbf4..40e3ec7f 100644 --- a/tests/rules/assertions/requireReturnType.js +++ b/tests/rules/assertions/requireReturnType.js @@ -201,7 +201,7 @@ export default { code: 'async () => {}', errors: [ { - message: 'Missing return type annotation.' + message: 'Must annotate undefined return type.' } ], options: [ @@ -215,7 +215,7 @@ export default { code: 'async function x() {}', errors: [ { - message: 'Missing return type annotation.' + message: 'Must annotate undefined return type.' } ], options: [ @@ -226,29 +226,49 @@ export default { ] }, { - code: 'class Test { constructor() { } }', + code: 'async (): Promise => { return; }', errors: [ { - message: 'Must annotate undefined return type.' + message: 'Must not annotate undefined return type.' } ], options: [ 'always', { - annotateUndefined: 'always' + annotateUndefined: 'never' } ] }, { - code: 'class Test { foo() { return 42; } }', + code: 'async (): Promise => { return; }', errors: [ { - message: 'Missing return type annotation.' + message: 'Must not annotate undefined return type.' + } + ], + options: [ + 'always', + { + annotateUndefined: 'never' } ] }, { - code: 'class Test { foo = () => { return 42; } }', + code: 'class Test { constructor() { } }', + errors: [ + { + message: 'Must annotate undefined return type.' + } + ], + options: [ + 'always', + { + annotateUndefined: 'always' + } + ] + }, + { + code: 'class Test { foo() { return 42; } }', errors: [ { message: 'Missing return type annotation.' @@ -256,7 +276,7 @@ export default { ] }, { - code: 'class Test { foo = () => 42; }', + code: 'class Test { foo = () => { return 42; } }', errors: [ { message: 'Missing return type annotation.' @@ -264,14 +284,11 @@ export default { ] }, { - code: 'async () => { return; }', + code: 'class Test { foo = () => 42; }', errors: [ { message: 'Missing return type annotation.' } - ], - options: [ - 'always' ] }, {