⬅️ Back to Table of Contents
📄 no-unnecessary-boolean-literal-compare.ts
📊 Analysis Summary
Metric |
Count |
🔧 Functions |
6 |
📦 Imports |
6 |
📊 Variables & Constants |
5 |
📐 Interfaces |
3 |
📑 Type Aliases |
2 |
📚 Table of Contents
🛠️ File Location:
📂 packages/eslint-plugin/src/rules/no-unnecessary-boolean-literal-compare.ts
📦 Imports
Name |
Source |
TSESTree |
@typescript-eslint/utils |
AST_NODE_TYPES |
@typescript-eslint/utils |
createRule |
../util |
getConstraintInfo |
../util |
getParserServices |
../util |
isStrongPrecedenceNode |
../util |
Variables & Constants
Name |
Type |
Kind |
Value |
Exported |
hasNonNullishType |
boolean |
const |
nonNullishTypes.length > 0 |
✗ |
hasNullableType |
boolean |
const |
nonNullishTypes.length < types.length |
✗ |
negated |
boolean |
const |
!comparisonType.isPositive |
✗ |
shouldNegate |
boolean |
let/var |
comparison.negated !== comparison.literalBooleanInComparison |
✗ |
mutatedNode |
any |
let/var |
isUnaryNegation ? node.parent : node |
✗ |
Functions
Code
function getBooleanComparison(
node: TSESTree.BinaryExpression,
): BooleanComparisonWithTypeInformation | undefined {
const comparison = deconstructComparison(node);
if (!comparison) {
return undefined;
}
const { constraintType, isTypeParameter } = getConstraintInfo(
checker,
services.getTypeAtLocation(comparison.expression),
);
if (isTypeParameter && constraintType == null) {
return undefined;
}
if (isBooleanType(constraintType)) {
return {
...comparison,
expressionIsNullableBoolean: false,
};
}
if (isNullableBoolean(constraintType)) {
return {
...comparison,
expressionIsNullableBoolean: true,
};
}
return undefined;
}
- Parameters:
node: TSESTree.BinaryExpression
- Return Type:
BooleanComparisonWithTypeInformation | undefined
- Calls:
deconstructComparison
getConstraintInfo (from ../util)
services.getTypeAtLocation
isBooleanType
isNullableBoolean
isBooleanType(expressionType: ts.Type): boolean
Code
function isBooleanType(expressionType: ts.Type): boolean {
return tsutils.isTypeFlagSet(
expressionType,
ts.TypeFlags.Boolean | ts.TypeFlags.BooleanLiteral,
);
}
- Parameters:
expressionType: ts.Type
- Return Type:
boolean
- Calls:
tsutils.isTypeFlagSet
isNullableBoolean(expressionType: ts.Type): boolean
Code
function isNullableBoolean(expressionType: ts.Type): boolean {
if (!expressionType.isUnion()) {
return false;
}
const { types } = expressionType;
const nonNullishTypes = types.filter(
type =>
!tsutils.isTypeFlagSet(
type,
ts.TypeFlags.Undefined | ts.TypeFlags.Null,
),
);
const hasNonNullishType = nonNullishTypes.length > 0;
if (!hasNonNullishType) {
return false;
}
const hasNullableType = nonNullishTypes.length < types.length;
if (!hasNullableType) {
return false;
}
const allNonNullishTypesAreBoolean = nonNullishTypes.every(isBooleanType);
if (!allNonNullishTypesAreBoolean) {
return false;
}
return true;
}
-
JSDoc:
/**
* checks if the expressionType is a union that
* 1) contains at least one nullish type (null or undefined)
* 2) contains at least once boolean type (true or false or boolean)
* 3) does not contain any types besides nullish and boolean types
*/
-
Parameters:
expressionType: ts.Type
- Return Type:
boolean
- Calls:
expressionType.isUnion
types.filter
tsutils.isTypeFlagSet
nonNullishTypes.every
deconstructComparison(node: TSESTree.BinaryExpression): BooleanComparison | undefined
Code
function deconstructComparison(
node: TSESTree.BinaryExpression,
): BooleanComparison | undefined {
const comparisonType = getEqualsKind(node.operator);
if (!comparisonType) {
return undefined;
}
for (const [against, expression] of [
[node.right, node.left],
[node.left, node.right],
]) {
if (
against.type !== AST_NODE_TYPES.Literal ||
typeof against.value !== 'boolean'
) {
continue;
}
const { value: literalBooleanInComparison } = against;
const negated = !comparisonType.isPositive;
return {
expression,
literalBooleanInComparison,
negated,
};
}
return undefined;
}
- Parameters:
node: TSESTree.BinaryExpression
- Return Type:
BooleanComparison | undefined
- Calls:
getEqualsKind
nodeIsUnaryNegation(node: TSESTree.Node): boolean
Code
function nodeIsUnaryNegation(node: TSESTree.Node): boolean {
return (
node.type === AST_NODE_TYPES.UnaryExpression &&
node.prefix &&
node.operator === '!'
);
}
- Parameters:
node: TSESTree.Node
- Return Type:
boolean
getEqualsKind(operator: string): EqualsKind | undefined
Code
function getEqualsKind(operator: string): EqualsKind | undefined {
switch (operator) {
case '!=':
return {
isPositive: false,
isStrict: false,
};
case '!==':
return {
isPositive: false,
isStrict: true,
};
case '==':
return {
isPositive: true,
isStrict: false,
};
case '===':
return {
isPositive: true,
isStrict: true,
};
default:
return undefined;
}
}
- Parameters:
operator: string
- Return Type:
EqualsKind | undefined
Interfaces
BooleanComparison
Interface Code
interface BooleanComparison {
expression: TSESTree.Expression | TSESTree.PrivateIdentifier;
literalBooleanInComparison: boolean;
negated: boolean;
}
Properties
Name |
Type |
Optional |
Description |
expression |
TSESTree.Expression | TSESTree.PrivateIdentifier |
✗ |
|
literalBooleanInComparison |
boolean |
✗ |
|
negated |
boolean |
✗ |
|
Interface Code
interface BooleanComparisonWithTypeInformation extends BooleanComparison {
expressionIsNullableBoolean: boolean;
}
Properties
Name |
Type |
Optional |
Description |
expressionIsNullableBoolean |
boolean |
✗ |
|
EqualsKind
Interface Code
interface EqualsKind {
isPositive: boolean;
isStrict: boolean;
}
Properties
Name |
Type |
Optional |
Description |
isPositive |
boolean |
✗ |
|
isStrict |
boolean |
✗ |
|
Type Aliases
MessageIds
type MessageIds = | 'comparingNullableToFalse'
| 'comparingNullableToTrueDirect'
| 'comparingNullableToTrueNegated'
| 'direct'
| 'negated'
| 'noStrictNullCheck';
Options
type Options = [
{
allowComparingNullableBooleansToFalse?: boolean;
allowComparingNullableBooleansToTrue?: boolean;
allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing?: boolean;
},
];