diff --git a/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts b/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts index 5493e84d271..d3f7751e8d3 100644 --- a/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts +++ b/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts @@ -215,11 +215,12 @@ export default util.createRule({ node.type === AST_NODE_TYPES.LogicalExpression && node.operator !== '??' ) { - checkNode(node.left, isTestExpr); + checkNode(node.left, true); // we ignore the right operand when not in a context of a test expression + // if the right operand is itself a logical expression, it will be checked separately if (isTestExpr) { - checkNode(node.right, isTestExpr); + checkNode(node.right, true); } return; } 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 b6da08b5965..d80ad566449 100644 --- a/packages/eslint-plugin/tests/rules/strict-boolean-expressions.test.ts +++ b/packages/eslint-plugin/tests/rules/strict-boolean-expressions.test.ts @@ -304,6 +304,67 @@ if (y) { ], }, + // a chain of logical operators should check every operand except the last one in a chain + { + options: [{ allowString: false, allowNumber: false }], + code: "'asd' && 123 && [] && null;", + errors: [ + { messageId: 'conditionErrorString', line: 1, column: 1 }, + { messageId: 'conditionErrorNumber', line: 1, column: 10 }, + { messageId: 'conditionErrorObject', line: 1, column: 17 }, + ], + }, + { + options: [{ allowString: false, allowNumber: false }], + code: "'asd' || 123 || [] || null;", + errors: [ + { messageId: 'conditionErrorString', line: 1, column: 1 }, + { messageId: 'conditionErrorNumber', line: 1, column: 10 }, + { messageId: 'conditionErrorObject', line: 1, column: 17 }, + ], + }, + { + options: [{ allowString: false, allowNumber: false }], + code: "(1 && 'a' && null) || 0 || '' || {};", + errors: [ + { messageId: 'conditionErrorNumber', line: 1, column: 2 }, + { messageId: 'conditionErrorString', line: 1, column: 7 }, + { messageId: 'conditionErrorNullish', line: 1, column: 14 }, + { messageId: 'conditionErrorNumber', line: 1, column: 23 }, + { messageId: 'conditionErrorString', line: 1, column: 28 }, + ], + }, + { + options: [{ allowString: false, allowNumber: false }], + code: "(1 || 'a' || null) && 0 && '' && {};", + errors: [ + { messageId: 'conditionErrorNumber', line: 1, column: 2 }, + { messageId: 'conditionErrorString', line: 1, column: 7 }, + { messageId: 'conditionErrorNullish', line: 1, column: 14 }, + { messageId: 'conditionErrorNumber', line: 1, column: 23 }, + { messageId: 'conditionErrorString', line: 1, column: 28 }, + ], + }, + { + options: [{ allowString: false, allowNumber: false }], + code: "(1 && []) || ('a' && {});", + errors: [ + { messageId: 'conditionErrorNumber', line: 1, column: 2 }, + { messageId: 'conditionErrorObject', line: 1, column: 7 }, + { messageId: 'conditionErrorString', line: 1, column: 15 }, + ], + }, + { + options: [{ allowString: false, allowNumber: false }], + code: "if ((1 && []) || ('a' && {})) void 0;", + errors: [ + { messageId: 'conditionErrorNumber', line: 1, column: 6 }, + { messageId: 'conditionErrorObject', line: 1, column: 11 }, + { messageId: 'conditionErrorString', line: 1, column: 19 }, + { messageId: 'conditionErrorObject', line: 1, column: 26 }, + ], + }, + // nullish in boolean context ...batchedSingleLineTests({ code: noFormat`