Skip to content

⬅️ Back to Table of Contents

📄 no-invalid-this

📊 Analysis Summary

Metric Count
🔧 Functions 1
📦 Imports 6
📊 Variables & Constants 1
📑 Type Aliases 2

📚 Table of Contents

🛠️ File Location:

📂 packages/eslint-plugin/src/rules/no-invalid-this.ts

📤 Default Export

export default createRule<Options, MessageIds>({ ... })
Property Value
name 'no-invalid-this'
meta.type 'suggestion'
meta.docs.description 'Disallow this keywords outside of classes or class-like objects'
meta.docs.extendsBaseRule true
meta.hasSuggestions baseRule.meta.hasSuggestions
meta.messages baseRule.meta.messages
meta.schema baseRule.meta.schema

Entry point: create — documented under Functions.


📦 Imports

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

Variables & Constants

Name Type Kind Value Exported
defaultOptions Options const [{ capIsConstructor: true }]

Functions

create(context: any): any

Parameters:

  • context any

Returns: any

Calls:

  • baseRule.create
  • thisIsValidStack.push
  • thisIsValidStack.pop
  • node.params.some
  • rules.ThisExpression

Internal Comments:

/**
     * Since function definitions can be nested we use a stack storing if "this" is valid in the current context.
     *
     * Example:
     *
     * function a(this: number) { // valid "this"
     *     function b() {
     *         console.log(this); // invalid "this"
     *     }
     * }
     *
     * When parsing the function declaration of "a" the stack will be: [true]
     * When parsing the function declaration of "b" the stack will be: [true, false]
     */ (x2)
// baseRule's work (x4)

Code
create(context) {
    const rules = baseRule.create(context);

    /**
     * Since function definitions can be nested we use a stack storing if "this" is valid in the current context.
     *
     * Example:
     *
     * function a(this: number) { // valid "this"
     *     function b() {
     *         console.log(this); // invalid "this"
     *     }
     * }
     *
     * When parsing the function declaration of "a" the stack will be: [true]
     * When parsing the function declaration of "b" the stack will be: [true, false]
     */
    const thisIsValidStack: boolean[] = [];

    return {
      ...rules,
      AccessorProperty(): void {
        thisIsValidStack.push(true);
      },
      'AccessorProperty:exit'(): void {
        thisIsValidStack.pop();
      },
      FunctionDeclaration(node: TSESTree.FunctionDeclaration): void {
        thisIsValidStack.push(
          node.params.some(
            param =>
              param.type === AST_NODE_TYPES.Identifier && param.name === 'this',
          ),
        );
      },
      'FunctionDeclaration:exit'(): void {
        thisIsValidStack.pop();
      },
      FunctionExpression(node: TSESTree.FunctionExpression): void {
        thisIsValidStack.push(
          node.params.some(
            param =>
              param.type === AST_NODE_TYPES.Identifier && param.name === 'this',
          ),
        );
      },
      'FunctionExpression:exit'(): void {
        thisIsValidStack.pop();
      },
      PropertyDefinition(): void {
        thisIsValidStack.push(true);
      },
      'PropertyDefinition:exit'(): void {
        thisIsValidStack.pop();
      },
      ThisExpression(node: TSESTree.ThisExpression): void {
        const thisIsValidHere = thisIsValidStack[thisIsValidStack.length - 1];

        if (thisIsValidHere) {
          return;
        }

        // baseRule's work
        rules.ThisExpression(node);
      },
    };
  }

Type Aliases

Options

type Options = InferOptionsTypeFromRule<typeof baseRule>;

MessageIds

type MessageIds = InferMessageIdsTypeFromRule<typeof baseRule>;

Generated by Syntax Scribe