From cf7801ec49d7673ceed5fd43ac3b4daf189c174e Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Sat, 14 Mar 2020 16:42:16 +1300 Subject: [PATCH 1/2] feat(eslint-plugin): allow concise arrows that start with void --- .../rules/explicit-function-return-type.md | 20 +++++++++++ .../rules/explicit-function-return-type.ts | 20 ++++++++++- .../explicit-function-return-type.test.ts | 35 +++++++++++++++++++ 3 files changed, 74 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..8d16d30c265 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,35 @@ 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: 1, + endLine: 1, + column: 13, + endColumn: 33, + }, + ], + }, ], }); From 09c5ece66d1b9c2846c28840c47b6e6c5cfaa736 Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Sun, 12 Apr 2020 20:29:02 +1200 Subject: [PATCH 2/2] chore(eslint-plugin): apply formatting --- .../rules/explicit-function-return-type.test.ts | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) 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 8d16d30c265..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 @@ -1060,15 +1060,19 @@ const func = (value: number) => ({ type: 'X', value } as const); }, { filename: 'test.ts', - code: 'const log = (message: string) => { void console.log(message); }', + code: ` + const log = (message: string) => { + void console.log(message); + }; + `, options: [{ allowConciseArrowFunctionExpressionsStartingWithVoid: true }], errors: [ { messageId: 'missingReturnType', - line: 1, - endLine: 1, - column: 13, - endColumn: 33, + line: 2, + endLine: 2, + column: 21, + endColumn: 41, }, ], },