From fd6be425a80567aa4f723b6d56bf550b66fe9371 Mon Sep 17 00:00:00 2001 From: Retsam Date: Wed, 24 Jul 2019 19:33:39 -0400 Subject: [PATCH] feat(eslint-plugin): [strict-boolean-expressions] add ignoreRhs option (#691) --- .../docs/rules/strict-boolean-expressions.md | 6 ++++ .../src/rules/strict-boolean-expressions.ts | 33 ++++++++++++++++--- .../rules/strict-boolean-expressions.test.ts | 30 +++++++++++++++++ 3 files changed, 64 insertions(+), 5 deletions(-) diff --git a/packages/eslint-plugin/docs/rules/strict-boolean-expressions.md b/packages/eslint-plugin/docs/rules/strict-boolean-expressions.md index 699af9baa43..de27437a47c 100644 --- a/packages/eslint-plugin/docs/rules/strict-boolean-expressions.md +++ b/packages/eslint-plugin/docs/rules/strict-boolean-expressions.md @@ -52,6 +52,12 @@ while (typeof str !== 'undefined') { } ``` +## Options + +Options may be provided as an object with: + +- `ignoreRhs` to skip the check on the right hand side of expressions like `a && b` or `a || b` - allows these operators to be used for their short-circuiting behavior. (`false` by default). + ## Related To - TSLint: [strict-boolean-expressions](https://palantir.github.io/tslint/rules/strict-boolean-expressions) diff --git a/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts b/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts index 5118b46a248..867c69d5f9e 100644 --- a/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts +++ b/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts @@ -13,7 +13,13 @@ type ExpressionWithTest = | TSESTree.IfStatement | TSESTree.WhileStatement; -export default util.createRule({ +type Options = [ + { + ignoreRhs?: boolean; + } +]; + +export default util.createRule({ name: 'strict-boolean-expressions', meta: { type: 'suggestion', @@ -22,13 +28,27 @@ export default util.createRule({ category: 'Best Practices', recommended: false, }, - schema: [], + schema: [ + { + type: 'object', + properties: { + ignoreRhs: { + type: 'boolean', + }, + }, + additionalProperties: false, + }, + ], messages: { strictBooleanExpression: 'Unexpected non-boolean in conditional.', }, }, - defaultOptions: [], - create(context) { + defaultOptions: [ + { + ignoreRhs: false, + }, + ], + create(context, [{ ignoreRhs }]) { const service = util.getParserServices(context); const checker = service.program.getTypeChecker(); @@ -65,7 +85,10 @@ export default util.createRule({ function assertLocalExpressionContainsBoolean( node: TSESTree.LogicalExpression, ): void { - if (!isBooleanType(node.left) || !isBooleanType(node.right)) { + if ( + !isBooleanType(node.left) || + (!ignoreRhs && !isBooleanType(node.right)) + ) { reportNode(node); } } diff --git a/packages/eslint-plugin/tests/rules/strict-boolean-expressions.test.ts b/packages/eslint-plugin/tests/rules/strict-boolean-expressions.test.ts index 030bade0f48..1067b5fa4c6 100644 --- a/packages/eslint-plugin/tests/rules/strict-boolean-expressions.test.ts +++ b/packages/eslint-plugin/tests/rules/strict-boolean-expressions.test.ts @@ -156,6 +156,15 @@ ruleTester.run('strict-boolean-expressions', rule, { ` function foo(arg: T) { return !arg; } `, + { + options: [{ ignoreRhs: true }], + code: ` +const obj = {}; +const bool = false; +const boolOrObj = bool || obj; +const boolAndObj = bool && obj; +`, + }, ], invalid: [ @@ -903,5 +912,26 @@ ruleTester.run('strict-boolean-expressions', rule, { }, ], }, + { + options: [{ ignoreRhs: true }], + errors: [ + { + messageId: 'strictBooleanExpression', + line: 4, + column: 19, + }, + { + messageId: 'strictBooleanExpression', + line: 5, + column: 20, + }, + ], + code: ` +const obj = {}; +const bool = false; +const objOrBool = obj || bool; +const objAndBool = obj && bool; +`, + }, ], });