Skip to content

⬅️ Back to Table of Contents

πŸ“„ no-unsafe-declaration-merging

πŸ“Š Analysis Summary

Metric Count
πŸ”§ Functions 2
πŸ“¦ Imports 4

πŸ“š Table of Contents

πŸ› οΈ File Location:

πŸ“‚ packages/eslint-plugin/src/rules/no-unsafe-declaration-merging.ts

πŸ“€ Default Export

export default createRule({ ... })
Property Value
name 'no-unsafe-declaration-merging'
meta.type 'problem'
meta.docs.description 'Disallow unsafe declaration merging'
meta.docs.recommended 'recommended'
meta.docs.requiresTypeChecking false
meta.messages.unsafeMerging 'Unsafe declaration merging between classes and interfaces.'
meta.schema []
defaultOptions []

Entry point: create β€” documented under Functions.


πŸ“¦ Imports

Name Source
Scope @typescript-eslint/scope-manager
TSESTree @typescript-eslint/utils
AST_NODE_TYPES @typescript-eslint/utils
createRule ../util

Functions

create(context: any): { ClassDeclaration(node: any): void; TSInterfaceDeclaration…

Parameters:

  • context any

Returns: { ClassDeclaration(node: any): void; TSInterfaceDeclaration(node: any): void; }

Calls:

  • scope.set.get
  • defs.some
  • context.report
  • context.sourceCode.getScope
  • checkUnsafeDeclaration

Internal Comments:

// by default eslint returns the inner class scope for the ClassDeclaration node (x2)
// but we want the outer scope within which merged variables will sit (x2)

Code
create(context) {
    function checkUnsafeDeclaration(
      scope: Scope,
      node: TSESTree.Identifier,
      unsafeKind: AST_NODE_TYPES,
    ): void {
      const variable = scope.set.get(node.name);
      if (!variable) {
        return;
      }

      const defs = variable.defs;
      if (defs.length <= 1) {
        return;
      }

      if (defs.some(def => def.node.type === unsafeKind)) {
        context.report({
          node,
          messageId: 'unsafeMerging',
        });
      }
    }

    return {
      ClassDeclaration(node): void {
        if (node.id) {
          // by default eslint returns the inner class scope for the ClassDeclaration node
          // but we want the outer scope within which merged variables will sit
          const currentScope = context.sourceCode.getScope(node).upper;
          if (currentScope == null) {
            return;
          }

          checkUnsafeDeclaration(
            currentScope,
            node.id,
            AST_NODE_TYPES.TSInterfaceDeclaration,
          );
        }
      },
      TSInterfaceDeclaration(node): void {
        checkUnsafeDeclaration(
          context.sourceCode.getScope(node),
          node.id,
          AST_NODE_TYPES.ClassDeclaration,
        );
      },
    };
  }

Internal helpers

Declared inside another function in this file.

checkUnsafeDeclaration(scope: Scope, node: TSESTree.Identifier, unsafeKind: AST_NODE_TYPES): void

Parameters:

  • scope Scope
  • node TSESTree.Identifier
  • unsafeKind AST_NODE_TYPES

Returns: void

Calls:

  • scope.set.get
  • defs.some
  • context.report
Code
function checkUnsafeDeclaration(
      scope: Scope,
      node: TSESTree.Identifier,
      unsafeKind: AST_NODE_TYPES,
    ): void {
      const variable = scope.set.get(node.name);
      if (!variable) {
        return;
      }

      const defs = variable.defs;
      if (defs.length <= 1) {
        return;
      }

      if (defs.some(def => def.node.type === unsafeKind)) {
        context.report({
          node,
          messageId: 'unsafeMerging',
        });
      }
    }

Generated by Syntax Scribe