From fd81f5d4f316eb0fd275b0743c80e213c29ced52 Mon Sep 17 00:00:00 2001 From: Kirk Waiblinger Date: Sat, 4 May 2024 00:52:34 -0600 Subject: [PATCH] [explicit-function-return-types] default parameters where a type annotation is present should count as typed function expressions fix https://github.com/typescript-eslint/typescript-eslint/issues/8950 --- .../src/util/explicitReturnTypeUtils.ts | 10 +++ .../explicit-function-return-type.test.ts | 74 +++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/packages/eslint-plugin/src/util/explicitReturnTypeUtils.ts b/packages/eslint-plugin/src/util/explicitReturnTypeUtils.ts index 2604e6185cc..f65273a502e 100644 --- a/packages/eslint-plugin/src/util/explicitReturnTypeUtils.ts +++ b/packages/eslint-plugin/src/util/explicitReturnTypeUtils.ts @@ -87,12 +87,22 @@ function isTypedParent( return ( isTypeAssertion(parent) || isVariableDeclaratorWithTypeAnnotation(parent) || + isDefaultFunctionParameterWithTypeAnnotation(parent) || isPropertyDefinitionWithTypeAnnotation(parent) || isFunctionArgument(parent, callee) || isTypedJSX(parent) ); } +function isDefaultFunctionParameterWithTypeAnnotation( + node: TSESTree.Node, +): boolean { + return ( + node.type === AST_NODE_TYPES.AssignmentPattern && + node.left.typeAnnotation != null + ); +} + /** * Checks if a node belongs to: * ``` diff --git a/packages/eslint-plugin/tests/rules/explicit-function-return-type.test.ts b/packages/eslint-plugin/tests/rules/explicit-function-return-type.test.ts index 7556cee3ce7..0e8c5182b7d 100644 --- a/packages/eslint-plugin/tests/rules/explicit-function-return-type.test.ts +++ b/packages/eslint-plugin/tests/rules/explicit-function-return-type.test.ts @@ -770,7 +770,32 @@ class Bar { } `, }, + { + code: ` +type CallBack = () => void; + +function f(gotcha: CallBack = () => {}): void {} + `, + options: [{ allowTypedFunctionExpressions: true }], + }, + { + code: ` +type CallBack = () => void; + +const f = (gotcha: CallBack = () => {}): void => {}; + `, + options: [{ allowTypedFunctionExpressions: true }], + }, + { + code: ` +type ObjectWithCallback = { callback: () => void }; + +const f = (gotcha: ObjectWithCallback = { callback: () => {} }): void => {}; + `, + options: [{ allowTypedFunctionExpressions: true }], + }, ], + invalid: [ { code: ` @@ -1940,5 +1965,54 @@ let foo = (() => () => {})()(); }, ], }, + { + code: ` +type CallBack = () => void; + +function f(gotcha: CallBack = () => {}): void {} + `, + options: [{ allowTypedFunctionExpressions: false }], + errors: [ + { + messageId: 'missingReturnType', + line: 4, + column: 34, + endLine: 4, + endColumn: 36, + }, + ], + }, + { + code: ` +type CallBack = () => void; + +const f = (gotcha: CallBack = () => {}): void => {}; + `, + options: [{ allowTypedFunctionExpressions: false }], + errors: [ + { + messageId: 'missingReturnType', + line: 4, + column: 34, + endLine: 4, + endColumn: 36, + }, + ], + }, + { + code: ` +type ObjectWithCallback = { callback: () => void }; + +const f = (gotcha: ObjectWithCallback = { callback: () => {} }): void => {}; + `, + options: [{ allowTypedFunctionExpressions: false }], + errors: [ + { + messageId: 'missingReturnType', + line: 4, + column: 43, + }, + ], + }, ], });