📄 no-unsafe-enum-comparison.ts
¶
📊 Analysis Summary¶
Metric | Count |
---|---|
🔧 Functions | 5 |
📦 Imports | 8 |
📊 Variables & Constants | 2 |
📚 Table of Contents¶
🛠️ File Location:¶
📂 packages/eslint-plugin/src/rules/no-unsafe-enum-comparison.ts
📦 Imports¶
Name | Source |
---|---|
TSESLint |
@typescript-eslint/utils |
TSESTree |
@typescript-eslint/utils |
createRule |
../util |
getParserServices |
../util |
getStaticValue |
../util |
getEnumKeyForLiteral |
./enum-utils/shared |
getEnumLiterals |
./enum-utils/shared |
getEnumTypes |
./enum-utils/shared |
Variables & Constants¶
Name | Type | Kind | Value | Exported |
---|---|---|---|---|
leftEnumValueTypes |
Set<any> |
const | new Set(leftTypeParts.map(getEnumValueType)) |
✗ |
rightEnumTypes |
Set<ts.Type> |
const | new Set(getEnumTypes(typeChecker, rightType)) |
✗ |
Functions¶
typeViolates(leftTypeParts: ts.Type[], rightType: ts.Type): boolean
¶
Code
function typeViolates(leftTypeParts: ts.Type[], rightType: ts.Type): boolean {
const leftEnumValueTypes = new Set(leftTypeParts.map(getEnumValueType));
return (
(leftEnumValueTypes.has(ts.TypeFlags.Number) && isNumberLike(rightType)) ||
(leftEnumValueTypes.has(ts.TypeFlags.String) && isStringLike(rightType))
);
}
-
JSDoc:
-
Parameters:
leftTypeParts: ts.Type[]
rightType: ts.Type
- Return Type:
boolean
- Calls:
leftTypeParts.map
leftEnumValueTypes.has
isNumberLike
isStringLike
isNumberLike(type: ts.Type): boolean
¶
Code
- Parameters:
type: ts.Type
- Return Type:
boolean
- Calls:
tsutils.intersectionConstituents
typeParts.some
tsutils.isTypeFlagSet
isStringLike(type: ts.Type): boolean
¶
Code
- Parameters:
type: ts.Type
- Return Type:
boolean
- Calls:
tsutils.intersectionConstituents
typeParts.some
tsutils.isTypeFlagSet
getEnumValueType(type: ts.Type): ts.TypeFlags | undefined
¶
Code
-
JSDoc:
-
Parameters:
type: ts.Type
- Return Type:
ts.TypeFlags | undefined
- Calls:
tsutils.isTypeFlagSet
isMismatchedComparison(leftType: ts.Type, rightType: ts.Type): boolean
¶
Code
function isMismatchedComparison(
leftType: ts.Type,
rightType: ts.Type,
): boolean {
// Allow comparisons that don't have anything to do with enums:
//
// ```ts
// 1 === 2;
// ```
const leftEnumTypes = getEnumTypes(typeChecker, leftType);
const rightEnumTypes = new Set(getEnumTypes(typeChecker, rightType));
if (leftEnumTypes.length === 0 && rightEnumTypes.size === 0) {
return false;
}
// Allow comparisons that share an enum type:
//
// ```ts
// Fruit.Apple === Fruit.Banana;
// ```
for (const leftEnumType of leftEnumTypes) {
if (rightEnumTypes.has(leftEnumType)) {
return false;
}
}
// We need to split the type into the union type parts in order to find
// valid enum comparisons like:
//
// ```ts
// declare const something: Fruit | Vegetable;
// something === Fruit.Apple;
// ```
const leftTypeParts = tsutils.unionConstituents(leftType);
const rightTypeParts = tsutils.unionConstituents(rightType);
// If a type exists in both sides, we consider this comparison safe:
//
// ```ts
// declare const fruit: Fruit.Apple | 0;
// fruit === 0;
// ```
for (const leftTypePart of leftTypeParts) {
if (rightTypeParts.includes(leftTypePart)) {
return false;
}
}
return (
typeViolates(leftTypeParts, rightType) ||
typeViolates(rightTypeParts, leftType)
);
}
- Parameters:
leftType: ts.Type
rightType: ts.Type
- Return Type:
boolean
- Calls:
getEnumTypes (from ./enum-utils/shared)
rightEnumTypes.has
tsutils.unionConstituents
rightTypeParts.includes
typeViolates
- Internal Comments:
// Allow comparisons that don't have anything to do with enums: (x2) // (x6) // ```ts (x6) // 1 === 2; (x2) // ``` (x6) // Allow comparisons that share an enum type: // Fruit.Apple === Fruit.Banana; // We need to split the type into the union type parts in order to find (x2) // valid enum comparisons like: (x2) // declare const something: Fruit | Vegetable; (x2) // something === Fruit.Apple; (x2) // If a type exists in both sides, we consider this comparison safe: // declare const fruit: Fruit.Apple | 0; // fruit === 0;