Skip to content

⬅️ Back to Table of Contents

📄 eqeq-nullish

📊 Analysis Summary

Metric Count
🔧 Functions 1
📦 Imports 4

📚 Table of Contents

🛠️ File Location:

📂 packages/eslint-plugin-internal/src/rules/eqeq-nullish.ts

📤 Default Export

export default createRule({ ... })
Property Value
name 'eqeq-nullish'
meta.type 'suggestion'
meta.docs.description 'Enforce eqeqeq preferences around nullish comparisons'
meta.fixable 'code'
meta.hasSuggestions true
meta.messages.unexpectedComparison 'Unexpected strict comparison ({{strictOperator}}) with {{nullishKind}}. In this codebase, we prefer to use loose...
meta.messages.useLooseComparisonSuggestion 'Use loose comparison ({{looseOperator}} null) instead, to check both nullish values.'
meta.schema []
defaultOptions []

Entry point: create — documented under Functions.


📦 Imports

Name Source
AST_NODE_TYPES @typescript-eslint/utils
nullThrows @typescript-eslint/utils/eslint-utils
NullThrowsReasons @typescript-eslint/utils/eslint-utils
createRule ../util/index.js

Functions

create(context: any): { BinaryExpression(node: any): void; }

Parameters:

  • context any

Returns: { BinaryExpression(node: any): void; }

Calls:

  • [node.left, node.right].find
  • nullThrows (from @typescript-eslint/utils/eslint-utils)
  • context.sourceCode.getFirstTokenBetween
  • NullThrowsReasons.MissingToken
  • context.report
  • fixer.replaceText
Code
create(context) {
    return {
      BinaryExpression(node): void {
        if (node.operator === '===' || node.operator === '!==') {
          const offendingChild = [node.left, node.right].find(
            child =>
              (child.type === AST_NODE_TYPES.Identifier &&
                child.name === 'undefined') ||
              (child.type === AST_NODE_TYPES.Literal && child.raw === 'null'),
          );

          if (offendingChild == null) {
            return;
          }

          const operatorToken = nullThrows(
            context.sourceCode.getFirstTokenBetween(
              node.left,
              node.right,
              token => token.value === node.operator,
            ),
            NullThrowsReasons.MissingToken(node.operator, 'binary expression'),
          );

          const wasLeft = node.left === offendingChild;

          const nullishKind =
            offendingChild.type === AST_NODE_TYPES.Identifier
              ? 'undefined'
              : 'null';

          const looseOperator = node.operator === '===' ? '==' : '!=';

          context.report({
            loc: wasLeft
              ? {
                  start: node.left.loc.start,
                  end: operatorToken.loc.end,
                }
              : {
                  start: operatorToken.loc.start,
                  end: node.right.loc.end,
                },

            messageId: 'unexpectedComparison',
            data: {
              nullishKind,
              strictOperator: node.operator,
            },
            suggest: [
              {
                messageId: 'useLooseComparisonSuggestion',
                data: {
                  looseOperator,
                },
                fix: fixer => [
                  fixer.replaceText(offendingChild, 'null'),
                  fixer.replaceText(operatorToken, looseOperator),
                ],
              },
            ],
          });
        }
      },
    };
  }

Generated by Syntax Scribe