From 2e9c2028a8a0b226e0f87d4bcc997fa259ca3ebd Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Mon, 13 Apr 2020 12:50:26 +1200 Subject: [PATCH] feat(eslint-plugin): [explicit-function-return-type] add option to allow concise arrows that start with void (#1732) --- .../rules/explicit-function-return-type.md | 20 ++++++++++ .../rules/explicit-function-return-type.ts | 20 +++++++++- .../explicit-function-return-type.test.ts | 39 +++++++++++++++++++ 3 files changed, 78 insertions(+), 1 deletion(-) 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 360fdce01e6..aa94a29a0ef 100644 --- a/packages/eslint-plugin/docs/rules/explicit-function-return-type.md +++ b/packages/eslint-plugin/docs/rules/explicit-function-return-type.md @@ -69,6 +69,8 @@ type Options = { allowTypedFunctionExpressions?: boolean; // if true, functions immediately returning another function expression will not be checked allowHigherOrderFunctions?: boolean; + // if true, concise arrow functions that start with the void keyword will not be checked + allowConciseArrowFunctionExpressionStartingWithVoid?: boolean; }; const defaults = { @@ -198,6 +200,24 @@ function fn() { } ``` +### `allowConciseArrowFunctionExpressionsStartingWithVoid` + +Examples of **incorrect** code for this rule with `{ allowConciseArrowFunctionExpressionsStartingWithVoid: true }`: + +```ts +var join = (a: string, b: string) => `${a}${b}`; + +const log = (message: string) => { + console.log(message); +}; +``` + +Examples of **correct** code for this rule with `{ allowConciseArrowFunctionExpressionsStartingWithVoid: true }`: + +```ts +var log = (message: string) => void console.log(message); +``` + ## 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 b8ee7ff584b..f0a5978d02f 100644 --- a/packages/eslint-plugin/src/rules/explicit-function-return-type.ts +++ b/packages/eslint-plugin/src/rules/explicit-function-return-type.ts @@ -1,4 +1,7 @@ -import { TSESTree } from '@typescript-eslint/experimental-utils'; +import { + AST_NODE_TYPES, + TSESTree, +} from '@typescript-eslint/experimental-utils'; import * as util from '../util'; import { checkFunctionReturnType, @@ -11,6 +14,7 @@ type Options = [ allowTypedFunctionExpressions?: boolean; allowHigherOrderFunctions?: boolean; allowDirectConstAssertionInArrowFunctions?: boolean; + allowConciseArrowFunctionExpressionsStartingWithVoid?: boolean; }, ]; type MessageIds = 'missingReturnType'; @@ -44,6 +48,9 @@ export default util.createRule({ allowDirectConstAssertionInArrowFunctions: { type: 'boolean', }, + allowConciseArrowFunctionExpressionsStartingWithVoid: { + type: 'boolean', + }, }, additionalProperties: false, }, @@ -55,6 +62,7 @@ export default util.createRule({ allowTypedFunctionExpressions: true, allowHigherOrderFunctions: true, allowDirectConstAssertionInArrowFunctions: true, + allowConciseArrowFunctionExpressionsStartingWithVoid: false, }, ], create(context, [options]) { @@ -64,6 +72,16 @@ export default util.createRule({ 'ArrowFunctionExpression, FunctionExpression'( node: TSESTree.ArrowFunctionExpression | TSESTree.FunctionExpression, ): void { + if ( + options.allowConciseArrowFunctionExpressionsStartingWithVoid && + node.type === AST_NODE_TYPES.ArrowFunctionExpression && + node.expression && + node.body.type === AST_NODE_TYPES.UnaryExpression && + node.body.operator === 'void' + ) { + return; + } + checkFunctionExpressionReturnType(node, options, sourceCode, loc => context.report({ node, 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 46ab4944185..dd3e3815676 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 @@ -366,6 +366,11 @@ new Foo(1, () => {}); }, ], }, + { + filename: 'test.ts', + code: 'const log = (message: string) => void console.log(message);', + options: [{ allowConciseArrowFunctionExpressionsStartingWithVoid: true }], + }, ], invalid: [ { @@ -1037,5 +1042,39 @@ const func = (value: number) => ({ type: 'X', value } as const); }, ], }, + { + filename: 'test.ts', + code: 'const log = (message: string) => void console.log(message);', + options: [ + { allowConciseArrowFunctionExpressionsStartingWithVoid: false }, + ], + errors: [ + { + messageId: 'missingReturnType', + line: 1, + endLine: 1, + column: 13, + endColumn: 33, + }, + ], + }, + { + filename: 'test.ts', + code: ` + const log = (message: string) => { + void console.log(message); + }; + `, + options: [{ allowConciseArrowFunctionExpressionsStartingWithVoid: true }], + errors: [ + { + messageId: 'missingReturnType', + line: 2, + endLine: 2, + column: 21, + endColumn: 41, + }, + ], + }, ], });