diff --git a/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts b/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts index dc6d09c75a65..fe79139486f1 100644 --- a/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts +++ b/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts @@ -730,7 +730,12 @@ export default util.createRule({ is('nullish', 'number', 'enum') || is('nullish', 'string', 'enum') || is('nullish', 'truthy number', 'enum') || - is('nullish', 'truthy string', 'enum') + is('nullish', 'truthy string', 'enum') || + // mixed enums + is('nullish', 'truthy number', 'truthy string', 'enum') || + is('nullish', 'truthy number', 'string', 'enum') || + is('nullish', 'truthy string', 'number', 'enum') || + is('nullish', 'number', 'string', 'enum') ) { if (!options.allowNullableEnum) { if (isLogicalNegationExpression(node.parent!)) { 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 1e33bae9889e..3994fc77313a 100644 --- a/packages/eslint-plugin/tests/rules/strict-boolean-expressions.test.ts +++ b/packages/eslint-plugin/tests/rules/strict-boolean-expressions.test.ts @@ -198,6 +198,53 @@ ruleTester.run('strict-boolean-expressions', rule, { `, options: [{ allowNullableEnum: true }], }, + + // nullable mixed enum in boolean context + { + // falsy number and truthy string + code: ` + enum ExampleEnum { + This = 0, + That = 'one', + } + (value?: ExampleEnum) => (value ? 1 : 0); + `, + options: [{ allowNullableEnum: true }], + }, + { + // falsy string and truthy number + code: ` + enum ExampleEnum { + This = '', + That = 1, + } + (value?: ExampleEnum) => (!value ? 1 : 0); + `, + options: [{ allowNullableEnum: true }], + }, + { + // truthy string and truthy number + code: ` + enum ExampleEnum { + This = 'this', + That = 1, + } + (value?: ExampleEnum) => (!value ? 1 : 0); + `, + options: [{ allowNullableEnum: true }], + }, + { + // falsy string and falsy number + code: ` + enum ExampleEnum { + This = '', + That = 0, + } + (value?: ExampleEnum) => (!value ? 1 : 0); + `, + options: [{ allowNullableEnum: true }], + }, + { code: ` declare const x: string[] | null; @@ -1287,6 +1334,117 @@ if (y) { } `, }, + + // nullable mixed enum in boolean context + { + // falsy number and truthy string + options: [{ allowNullableEnum: false }], + code: ` + enum ExampleEnum { + This = 0, + That = 'one', + } + (value?: ExampleEnum) => (value ? 1 : 0); + `, + errors: [ + { + line: 6, + column: 35, + messageId: 'conditionErrorNullableEnum', + endLine: 6, + endColumn: 40, + }, + ], + output: ` + enum ExampleEnum { + This = 0, + That = 'one', + } + (value?: ExampleEnum) => ((value != null) ? 1 : 0); + `, + }, + { + // falsy string and truthy number + options: [{ allowNullableEnum: false }], + code: ` + enum ExampleEnum { + This = '', + That = 1, + } + (value?: ExampleEnum) => (!value ? 1 : 0); + `, + errors: [ + { + line: 6, + column: 36, + messageId: 'conditionErrorNullableEnum', + endLine: 6, + endColumn: 41, + }, + ], + output: ` + enum ExampleEnum { + This = '', + That = 1, + } + (value?: ExampleEnum) => ((value == null) ? 1 : 0); + `, + }, + { + // truthy string and truthy number + options: [{ allowNullableEnum: false }], + code: ` + enum ExampleEnum { + This = 'this', + That = 1, + } + (value?: ExampleEnum) => (!value ? 1 : 0); + `, + errors: [ + { + line: 6, + column: 36, + messageId: 'conditionErrorNullableEnum', + endLine: 6, + endColumn: 41, + }, + ], + output: ` + enum ExampleEnum { + This = 'this', + That = 1, + } + (value?: ExampleEnum) => ((value == null) ? 1 : 0); + `, + }, + { + // falsy string and falsy number + options: [{ allowNullableEnum: false }], + code: ` + enum ExampleEnum { + This = '', + That = 0, + } + (value?: ExampleEnum) => (!value ? 1 : 0); + `, + errors: [ + { + line: 6, + column: 36, + messageId: 'conditionErrorNullableEnum', + endLine: 6, + endColumn: 41, + }, + ], + output: ` + enum ExampleEnum { + This = '', + That = 0, + } + (value?: ExampleEnum) => ((value == null) ? 1 : 0); + `, + }, + // any in boolean context ...batchedSingleLineTests({ code: noFormat`