Skip to content

⬅️ Back to Table of Contents

πŸ“„ no-extraneous-class

πŸ“Š Analysis Summary

Metric Count
πŸ”§ Functions 2
πŸ“¦ Imports 3
πŸ“‘ Type Aliases 2

πŸ“š Table of Contents

πŸ› οΈ File Location:

πŸ“‚ packages/eslint-plugin/src/rules/no-extraneous-class.ts

πŸ“€ Default Export

export default createRule<Options, MessageIds>({ ... })
Property Value
name 'no-extraneous-class'
meta.type 'suggestion'
meta.docs.description 'Disallow classes used as namespaces'
meta.docs.recommended 'strict'
meta.messages.empty 'Unexpected empty class.'
meta.messages.onlyConstructor 'Unexpected class with only a constructor.'
meta.messages.onlyStatic 'Unexpected class with only static properties.'
meta.schema [ { type: 'object', additionalProperties: false, properties: { allowConstructorOnly: { type: 'boolean', description: ...
defaultOptions [ { allowConstructorOnly: false, allowEmpty: false, allowStaticOnly: false, allowWithDecorator: false, }, ]

Entry point: create β€” documented under Functions.


πŸ“¦ Imports

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

Functions

create(context: any, [{ allowConstructorOnly, allowE…: any): { ClassBody(node: any): void; }

Parameters:

  • context any
  • [{ allowConstructorOnly, allowEmpty, allowStaticOnly, allowWithDecorator }] any

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

Calls:

  • isAllowWithDecorator
  • context.report
  • prop.value.params.some
Code
create(
    context,
    [{ allowConstructorOnly, allowEmpty, allowStaticOnly, allowWithDecorator }],
  ) {
    const isAllowWithDecorator = (
      node: TSESTree.ClassDeclaration | TSESTree.ClassExpression | undefined,
    ): boolean => {
      return !!(
        allowWithDecorator &&
        node?.decorators &&
        node.decorators.length !== 0
      );
    };

    return {
      ClassBody(node): void {
        const parent = node.parent;

        if (parent.superClass || isAllowWithDecorator(parent)) {
          return;
        }

        const reportNode =
          parent.type === AST_NODE_TYPES.ClassDeclaration && parent.id
            ? parent.id
            : parent;
        if (node.body.length === 0) {
          if (allowEmpty) {
            return;
          }

          context.report({
            node: reportNode,
            messageId: 'empty',
          });

          return;
        }

        let onlyStatic = true;
        let onlyConstructor = true;

        for (const prop of node.body) {
          if (
            prop.type === AST_NODE_TYPES.MethodDefinition &&
            prop.kind === 'constructor'
          ) {
            if (
              prop.value.params.some(
                param => param.type === AST_NODE_TYPES.TSParameterProperty,
              )
            ) {
              onlyConstructor = false;
              onlyStatic = false;
            }
          } else {
            onlyConstructor = false;
            if (
              ((prop.type === AST_NODE_TYPES.PropertyDefinition ||
                prop.type === AST_NODE_TYPES.MethodDefinition ||
                prop.type === AST_NODE_TYPES.AccessorProperty) &&
                !prop.static) ||
              prop.type === AST_NODE_TYPES.TSIndexSignature ||
              prop.type === AST_NODE_TYPES.TSAbstractPropertyDefinition ||
              prop.type === AST_NODE_TYPES.TSAbstractMethodDefinition || // `static abstract` methods and properties are currently not supported. See: https://github.com/microsoft/TypeScript/issues/34516
              prop.type === AST_NODE_TYPES.TSAbstractAccessorProperty
            ) {
              onlyStatic = false;
            }
          }
          if (!(onlyStatic || onlyConstructor)) {
            break;
          }
        }

        if (onlyConstructor) {
          if (!allowConstructorOnly) {
            context.report({
              node: reportNode,
              messageId: 'onlyConstructor',
            });
          }
          return;
        }
        if (onlyStatic && !allowStaticOnly) {
          context.report({
            node: reportNode,
            messageId: 'onlyStatic',
          });
        }
      },
    };
  }

Internal helpers

Declared inside another function in this file.

isAllowWithDecorator(node: TSESTree.ClassDeclaration | TSESTree.Cl…): boolean

Parameters:

  • node TSESTree.ClassDeclaration | TSESTree.ClassExpression | undefined

Returns: boolean

Code
(
      node: TSESTree.ClassDeclaration | TSESTree.ClassExpression | undefined,
    ): boolean => {
      return !!(
        allowWithDecorator &&
        node?.decorators &&
        node.decorators.length !== 0
      );
    }

Type Aliases

Options

type Options = [
  {
    allowConstructorOnly?: boolean;
    allowEmpty?: boolean;
    allowStaticOnly?: boolean;
    allowWithDecorator?: boolean;
  },
];

MessageIds

type MessageIds = 'empty' | 'onlyConstructor' | 'onlyStatic';

Generated by Syntax Scribe