Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
fix(eslint-plugin): [explicit-module-boundary-types] handle bodyless …
…arrow functions with explicit return types that return functions (#2169)
  • Loading branch information
bradzacher committed Jun 3, 2020
1 parent e4c1834 commit 58db655
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 22 deletions.
Expand Up @@ -402,7 +402,7 @@ export default util.createRule<Options, MessageIds>({
if (
isAllowedName(node.parent) ||
isTypedFunctionExpression(node, options) ||
ancestorHasReturnType(node.parent, options)
ancestorHasReturnType(node.parent)
) {
return;
}
Expand All @@ -424,10 +424,7 @@ export default util.createRule<Options, MessageIds>({
}
checkedFunctions.add(node);

if (
isAllowedName(node.parent) ||
ancestorHasReturnType(node.parent, options)
) {
if (isAllowedName(node.parent) || ancestorHasReturnType(node.parent)) {
return;
}

Expand Down
25 changes: 8 additions & 17 deletions packages/eslint-plugin/src/util/explicitReturnTypeUtils.ts
Expand Up @@ -300,10 +300,8 @@ function isValidFunctionExpressionReturnType(
function isValidFunctionReturnType(
node: FunctionNode,
options: Options,
isParentCheck = false,
): boolean {
if (
!isParentCheck &&
options.allowHigherOrderFunctions &&
doesImmediatelyReturnFunctionExpression(node)
) {
Expand Down Expand Up @@ -353,29 +351,22 @@ function checkFunctionExpressionReturnType(
* Check whether any ancestor of the provided node has a valid return type, with
* the given options.
*/
function ancestorHasReturnType(
ancestor: TSESTree.Node | undefined,
options: Options,
): boolean {
// Exit early if this ancestor is not a ReturnStatement.
if (ancestor?.type !== AST_NODE_TYPES.ReturnStatement) {
function ancestorHasReturnType(ancestor: TSESTree.Node | undefined): boolean {
// if the ancestor is not a return, then this function was not returned at all, so we can exit early
const isReturnStatne = ancestor?.type === AST_NODE_TYPES.ReturnStatement;
const isBodylessArrow =
ancestor?.type === AST_NODE_TYPES.ArrowFunctionExpression &&
ancestor.body.type !== AST_NODE_TYPES.BlockStatement;
if (!isReturnStatne && !isBodylessArrow) {
return false;
}

// This boolean tells the `isValidFunctionReturnType` that it is being called
// by an ancestor check.
const isParentCheck = true;

while (ancestor) {
switch (ancestor.type) {
case AST_NODE_TYPES.ArrowFunctionExpression:
case AST_NODE_TYPES.FunctionExpression:
return (
isValidFunctionExpressionReturnType(ancestor, options) ||
isValidFunctionReturnType(ancestor, options, isParentCheck)
);
case AST_NODE_TYPES.FunctionDeclaration:
return isValidFunctionReturnType(ancestor, options, isParentCheck);
return ancestor.returnType != null;
}

ancestor = ancestor.parent;
Expand Down
Expand Up @@ -618,6 +618,12 @@ export function foo(...[a]: any): void {}
`
export function foo(arg = 1): void {}
`,
// https://github.com/typescript-eslint/typescript-eslint/issues/2161
{
code: `
export const foo = (): ((n: number) => string) => n => String(n);
`,
},
],
invalid: [
{
Expand Down

0 comments on commit 58db655

Please sign in to comment.