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..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 @@ -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: [ + { + line: 12, + messageId: 'mismatchedCase', + }, + { + line: 13, + messageId: 'mismatchedCase', + }, + ], + }, + { + 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: [ + { + line: 12, + messageId: 'mismatchedCase', + }, + { + line: 13, + messageId: 'mismatchedCase', + }, + ], + }, + { + code: ` +declare const stringUnion: 'foo' | 'bar'; + +enum StringEnum { + FOO = 'foo', + BAR = 'bar', +} + +declare const stringEnum: StringEnum; + +stringUnion === stringEnum; + `, + errors: [ + { + line: 11, + messageId: 'mismatchedCondition', + }, + ], + }, ], });