Skip to content

Commit

Permalink
tweak(eslint-plugin): [no-unsafe-enum-comparison] add switch suggestion
Browse files Browse the repository at this point in the history
Closes #7643
  • Loading branch information
StyleShit committed Sep 24, 2023
1 parent 4e23591 commit 8725058
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 9 deletions.
66 changes: 61 additions & 5 deletions packages/eslint-plugin/src/rules/no-unsafe-enum-comparison.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,27 @@ function typeViolates(leftTypeParts: ts.Type[], right: ts.Type): boolean {
);
}

function getEnumKeyForLiteral(
leftEnumTypes: ts.Type[],
rightNode: TSESTree.Node,
): string | null {
const right = util.getStaticValue(rightNode);

if (right === null) {
return null;
}

for (const leftEnumType of leftEnumTypes) {
if (leftEnumType.value === right.value) {
const enumParentName = leftEnumType.symbol.parent.name;

return `${enumParentName}.${leftEnumType.symbol.name}`;
}
}

return null;
}

/**
* @returns What type a type's enum value is (number or string), if either.
*/
Expand All @@ -48,6 +69,8 @@ export default util.createRule({
messages: {
mismatched:
'The two values in this comparison do not have a shared enum type.',
mismatchedSimilar:
'The two values in this comparison do not have a shared enum type. Did you mean to compare to `{{replacement}}`?',
},
schema: [],
},
Expand Down Expand Up @@ -100,11 +123,44 @@ export default util.createRule({
}
}

if (
typeViolates(leftTypeParts, right) ||
typeViolates(rightTypeParts, left)
) {
context.report({
if (typeViolates(leftTypeParts, right)) {
const leftEnumKey = getEnumKeyForLiteral(leftEnumTypes, node.right);

if (leftEnumKey) {
// TODO: Add fixer.
return context.report({
messageId: 'mismatchedSimilar',
node,
data: {
replacement: leftEnumKey,
},
});
}

return context.report({
messageId: 'mismatched',
node,
});
}

if (typeViolates(rightTypeParts, left)) {
const rightEnumKey = getEnumKeyForLiteral(
[...rightEnumTypes.values()],
node.left,
);

if (rightEnumKey) {
// TODO: Add fixer.
return context.report({
messageId: 'mismatchedSimilar',
node,
data: {
replacement: rightEnumKey,
},
});
}

return context.report({
messageId: 'mismatched',
node,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -545,10 +545,22 @@ ruleTester.run('strict-enums-comparison', rule, {
mixed === 1;
`,
errors: [
{ messageId: 'mismatched' },
{ messageId: 'mismatched' },
{ messageId: 'mismatched' },
{ messageId: 'mismatched' },
{
message:
'The two values in this comparison do not have a shared enum type. Did you mean to compare to `Str.A`?',
},
{
message:
'The two values in this comparison do not have a shared enum type. Did you mean to compare to `Num.B`?',
},
{
message:
'The two values in this comparison do not have a shared enum type. Did you mean to compare to `Mixed.A`?',
},
{
message:
'The two values in this comparison do not have a shared enum type. Did you mean to compare to `Mixed.B`?',
},
],
},
{
Expand Down

0 comments on commit 8725058

Please sign in to comment.