diff --git a/packages/eslint-plugin/docs/rules/explicit-function-return-type.md b/packages/eslint-plugin/docs/rules/explicit-function-return-type.md index 3a67a7e23721..a5df82f958ab 100644 --- a/packages/eslint-plugin/docs/rules/explicit-function-return-type.md +++ b/packages/eslint-plugin/docs/rules/explicit-function-return-type.md @@ -257,6 +257,26 @@ You may pass function/method names you would like this rule to ignore, like so: } ``` +### `allowIIFE` + +Examples of code for this rule with `{ allowIIFE: true }`: + +#### ❌ Incorrect + +```ts +var func = () => 'foo'; +``` + +#### ✅ Correct + +```ts +var foo = (() => 'foo')(); + +var bar = (function () { + return 'bar'; +})(); +``` + ## When Not To Use It If you don't wish to prevent calling code from using function return values in unexpected ways, then diff --git a/packages/eslint-plugin/src/rules/explicit-function-return-type.ts b/packages/eslint-plugin/src/rules/explicit-function-return-type.ts index 9c91aa6d83d9..254c48a0965c 100644 --- a/packages/eslint-plugin/src/rules/explicit-function-return-type.ts +++ b/packages/eslint-plugin/src/rules/explicit-function-return-type.ts @@ -17,6 +17,7 @@ type Options = [ allowConciseArrowFunctionExpressionsStartingWithVoid?: boolean; allowFunctionsWithoutTypeParameters?: boolean; allowedNames?: string[]; + allowIIFEs?: boolean; }, ]; type MessageIds = 'missingReturnType'; @@ -75,6 +76,11 @@ export default util.createRule({ }, type: 'array', }, + allowIIFEs: { + description: + 'Whether to ignore immediately invoked function expressions (IIFEs).', + type: 'boolean', + }, }, additionalProperties: false, }, @@ -88,6 +94,7 @@ export default util.createRule({ allowDirectConstAssertionInArrowFunctions: true, allowConciseArrowFunctionExpressionsStartingWithVoid: false, allowedNames: [], + allowIIFEs: false, }, ], create(context, [options]) { @@ -102,6 +109,10 @@ export default util.createRule({ return true; } + if (options.allowIIFEs && isIIFE(node)) { + return true; + } + if (!options.allowedNames?.length) { return false; } @@ -149,6 +160,16 @@ export default util.createRule({ } return false; } + + function isIIFE( + node: + | TSESTree.ArrowFunctionExpression + | TSESTree.FunctionExpression + | TSESTree.FunctionDeclaration, + ): boolean { + return node.parent!.type === AST_NODE_TYPES.CallExpression; + } + return { 'ArrowFunctionExpression, FunctionExpression'( node: TSESTree.ArrowFunctionExpression | TSESTree.FunctionExpression, 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 912242247af7..d3c1a5401926 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 @@ -595,6 +595,132 @@ const x: Bar = arg1 => arg2 => arg1 + arg2; }, ], }, + { + filename: 'test.ts', + code: ` +let foo = function (): number { + return 1; +}; + `, + options: [ + { + allowIIFEs: true, + }, + ], + }, + { + filename: 'test.ts', + code: ` +const foo = (function () { + return 1; +})(); + `, + options: [ + { + allowIIFEs: true, + }, + ], + }, + { + filename: 'test.ts', + code: ` +const foo = (() => { + return 1; +})(); + `, + options: [ + { + allowIIFEs: true, + }, + ], + }, + { + filename: 'test.ts', + code: ` +const foo = ((arg: number): number => { + return arg; +})(0); + `, + options: [ + { + allowIIFEs: true, + }, + ], + }, + { + filename: 'test.ts', + code: ` +const foo = (() => (() => 'foo')())(); + `, + options: [ + { + allowIIFEs: true, + }, + ], + }, + { + filename: 'test.ts', + code: ` +let foo = (() => (): string => { + return 'foo'; +})()(); + `, + options: [ + { + allowIIFEs: true, + }, + ], + }, + { + filename: 'test.ts', + code: ` +let foo = (() => (): string => { + return 'foo'; +})(); + `, + options: [ + { + allowIIFEs: true, + allowHigherOrderFunctions: false, + }, + ], + }, + { + filename: 'test.ts', + code: ` +let foo = (() => (): string => { + return 'foo'; +})()(); + `, + options: [ + { + allowIIFEs: true, + allowHigherOrderFunctions: true, + }, + ], + }, + { + filename: 'test.ts', + code: ` +let foo = (() => (): void => {})()(); + `, + options: [ + { + allowIIFEs: true, + }, + ], + }, + { + filename: 'test.ts', + code: ` +let foo = (() => (() => {})())(); + `, + options: [ + { + allowIIFEs: true, + }, + ], + }, ], invalid: [ { @@ -1477,5 +1603,93 @@ class Foo { }, ], }, + { + filename: 'test.ts', + code: ` +const foo = (function () { + return 'foo'; +})(); + `, + options: [ + { + allowIIFEs: false, + }, + ], + errors: [ + { + messageId: 'missingReturnType', + line: 2, + endLine: 2, + column: 14, + endColumn: 25, + }, + ], + }, + { + filename: 'test.ts', + code: ` +const foo = (function () { + return () => { + return 1; + }; +})(); + `, + options: [ + { + allowIIFEs: true, + }, + ], + errors: [ + { + messageId: 'missingReturnType', + line: 3, + endLine: 3, + column: 10, + endColumn: 15, + }, + ], + }, + { + filename: 'test.ts', + code: ` +let foo = function () { + return 'foo'; +}; + `, + options: [ + { + allowIIFEs: true, + }, + ], + errors: [ + { + messageId: 'missingReturnType', + line: 2, + endLine: 2, + column: 11, + endColumn: 22, + }, + ], + }, + { + filename: 'test.ts', + code: ` +let foo = (() => () => {})()(); + `, + options: [ + { + allowIIFEs: true, + }, + ], + errors: [ + { + messageId: 'missingReturnType', + line: 2, + endLine: 2, + column: 18, + endColumn: 23, + }, + ], + }, ], }); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy