From f502178d5c7ba94005a9f5b852a6d56ce02ae39c Mon Sep 17 00:00:00 2001 From: Kirk Waiblinger <53019676+kirkwaiblinger@users.noreply.github.com> Date: Fri, 12 Sep 2025 15:13:18 -0600 Subject: [PATCH 1/2] fix(eslint-plugin): [no-unsafe-enum-comparison] support unions of literals --- .../src/rules/no-unsafe-enum-comparison.ts | 36 +++++---- .../rules/no-unsafe-enum-comparison.test.ts | 76 +++++++++++++++++++ 2 files changed, 98 insertions(+), 14 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-unsafe-enum-comparison.ts b/packages/eslint-plugin/src/rules/no-unsafe-enum-comparison.ts index c5f457db3618..051a827ee720 100644 --- a/packages/eslint-plugin/src/rules/no-unsafe-enum-comparison.ts +++ b/packages/eslint-plugin/src/rules/no-unsafe-enum-comparison.ts @@ -23,25 +23,33 @@ function typeViolates(leftTypeParts: ts.Type[], rightType: ts.Type): boolean { } function isNumberLike(type: ts.Type): boolean { - const typeParts = tsutils.intersectionConstituents(type); - - return typeParts.some(typePart => { - return tsutils.isTypeFlagSet( - typePart, - ts.TypeFlags.Number | ts.TypeFlags.NumberLike, + return tsutils + .unionConstituents(type) + .every(unionPart => + tsutils + .intersectionConstituents(unionPart) + .some(intersectionPart => + tsutils.isTypeFlagSet( + intersectionPart, + ts.TypeFlags.Number | ts.TypeFlags.NumberLike, + ), + ), ); - }); } function isStringLike(type: ts.Type): boolean { - const typeParts = tsutils.intersectionConstituents(type); - - return typeParts.some(typePart => { - return tsutils.isTypeFlagSet( - typePart, - ts.TypeFlags.String | ts.TypeFlags.StringLike, + return tsutils + .unionConstituents(type) + .every(unionPart => + tsutils + .intersectionConstituents(unionPart) + .some(intersectionPart => + tsutils.isTypeFlagSet( + intersectionPart, + ts.TypeFlags.String | ts.TypeFlags.StringLike, + ), + ), ); - }); } /** diff --git a/packages/eslint-plugin/tests/rules/no-unsafe-enum-comparison.test.ts b/packages/eslint-plugin/tests/rules/no-unsafe-enum-comparison.test.ts index 89e28f163314..605ed0113ece 100644 --- a/packages/eslint-plugin/tests/rules/no-unsafe-enum-comparison.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unsafe-enum-comparison.test.ts @@ -1165,5 +1165,81 @@ ruleTester.run('no-unsafe-enum-comparison', rule, { `, errors: [{ messageId: 'mismatchedCondition' }], }, + { + code: ` +enum NUMBER_ENUM { + First = 0, + Second = 1, +} + +type NumberUnion = 0 | 1; + +declare const numberUnion: NumberUnion; + +switch (numberUnion) { + case NUMBER_ENUM.First: + case NUMBER_ENUM.Second: + break; +} + `, + errors: [ + { + messageId: 'mismatchedCase', + line: 12, + }, + { + messageId: 'mismatchedCase', + line: 13, + }, + ], + }, + { + code: ` +enum STRING_ENUM { + First = 'one', + Second = 'two', +} + +type StringUnion = 'one' | 'two'; + +declare const stringUnion: StringUnion; + +switch (stringUnion) { + case STRING_ENUM.First: + case STRING_ENUM.Second: + break; +} + `, + errors: [ + { + messageId: 'mismatchedCase', + line: 12, + }, + { + messageId: 'mismatchedCase', + line: 13, + }, + ], + }, + { + code: ` +declare const stringUnion: 'foo' | 'bar'; + +enum StringEnum { + FOO = 'foo', + BAR = 'bar', +} + +declare const stringEnum: StringEnum; + +stringUnion === stringEnum; + `, + errors: [ + { + messageId: 'mismatchedCondition', + line: 11, + }, + ], + }, ], }); From e74b701db026a3379adbfb000566ceb433493ef1 Mon Sep 17 00:00:00 2001 From: Kirk Waiblinger <53019676+kirkwaiblinger@users.noreply.github.com> Date: Fri, 12 Sep 2025 15:48:39 -0600 Subject: [PATCH 2/2] lint fix --- .../tests/rules/no-unsafe-enum-comparison.test.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/eslint-plugin/tests/rules/no-unsafe-enum-comparison.test.ts b/packages/eslint-plugin/tests/rules/no-unsafe-enum-comparison.test.ts index 605ed0113ece..b10f3cc6ee5f 100644 --- a/packages/eslint-plugin/tests/rules/no-unsafe-enum-comparison.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unsafe-enum-comparison.test.ts @@ -1184,12 +1184,12 @@ switch (numberUnion) { `, errors: [ { - messageId: 'mismatchedCase', line: 12, + messageId: 'mismatchedCase', }, { - messageId: 'mismatchedCase', line: 13, + messageId: 'mismatchedCase', }, ], }, @@ -1212,12 +1212,12 @@ switch (stringUnion) { `, errors: [ { - messageId: 'mismatchedCase', line: 12, + messageId: 'mismatchedCase', }, { - messageId: 'mismatchedCase', line: 13, + messageId: 'mismatchedCase', }, ], }, @@ -1236,8 +1236,8 @@ stringUnion === stringEnum; `, errors: [ { - messageId: 'mismatchedCondition', line: 11, + messageId: 'mismatchedCondition', }, ], },