Skip to content

Latest commit

 

History

History
108 lines (78 loc) · 2.25 KB

README.md

File metadata and controls

108 lines (78 loc) · 2.25 KB

Description

Class method functions don't preserve the class scope when passed as standalone variables ("unbound").

If your function does not access this, you can annotate it with this: void, or consider using an arrow function instead.

Otherwise, passing class methods around as values can remove type safety by failing to capture this.

This rule reports when a class method is referenced in an unbound manner.

This rule forked from the base rule of eslint but with support for the ignore option.

Examples

❌ Incorrect

class MyClass {
  public log(): void {
    console.log(this);
  }
}

const instance = new MyClass();

// This logs the global scope (`window`/`global`), not the class instance
const myLog = instance.log;
myLog();

// This log might later be called with an incorrect scope
const { log } = instance;

// arith.double may refer to `this` internally
const arith = {
  double(x: number): number {
    return x * 2;
  },
};
const { double } = arith;

✅ Correct

class MyClass {
  public logUnbound(): void {
    console.log(this);
  }

  public logBound = () => console.log(this);
}

const instance = new MyClass();

// logBound will always be bound with the correct scope
const { logBound } = instance;
logBound();

// .bind and lambdas will also add a correct scope
const dotBindLog = instance.logBound.bind(instance);
const innerLog = () => instance.logBound();

// arith.double explicitly declares that it does not refer to `this` internally
const arith = {
  double(this: void, x: number): number {
    return x * 2;
  },
};
const { double } = arith;

Options

ignoreStatic

Examples of correct code for this rule with { ignoreStatic: true }:

class OtherClass {
  static log() {
    console.log(OtherClass);
  }
}

// With `ignoreStatic`, statics are assumed to not rely on a particular scope
const { log } = OtherClass;

log();

ignore

Examples of correct code for this rule with { ignore: [Object] }

class OtherClass {
  val = 0;

  isTruthyValue(checker) {
    return checker(val);
  }

  magicMethod(val) {
    const isMagic = this.isTruthyValue(Object.isObject);
    return isMagic;
  }
}