Skip to content
NewBun 1.4.5 is out. Release notes
AphrodyBun

Linter · Rules

class-methods-use-this

Require class methods to use this

A method that never touches this doesn't need an instance, but callers still have to create one to call it. Make it static, or move it out of the class as a plain function.

The rule checks methods, getters, setters, and fields that hold a function. Constructors and static members aren't checked. Using super counts as using this.

Configure

Off by default. To turn it on:

bunfig.toml
[lint.rules]
"class-methods-use-this" = "error" # or "warn"

Every option, set to its default. The ones that are commented out are unset by default.

bunfig.toml
[lint.rules]
"class-methods-use-this" = ["error", {
  exceptMethods = [], # list of strings
  enforceForClassFields = true,
  ignoreOverrideMethods = false,
  # ignoreClassesWithImplements = <"all" or "public-fields">,
}]

Examples

Reported:

class Cart {
  formatPrice(cents) {
    return "$" + (cents / 100).toFixed(2);
  }
}

Not reported:

class Cart {
  static formatPrice(cents) {
    return "$" + (cents / 100).toFixed(2);
  }

  total() {
    return Cart.formatPrice(this.items.reduce((sum, item) => sum + item.cents, 0));
  }
}

Options

OptionDefaultWhat it does
exceptMethods[]Method names to skip. Write a private method with its #.
enforceForClassFieldstrueAlso check fields that hold a function, like format = () => {}.
ignoreOverrideMethodsfalseDon't check members marked override in TypeScript.
ignoreClassesWithImplementsnot set"all" skips every member of a class that has an implements clause. "public-fields" skips only its public members.

A framework may call a method on the instance whether it uses this or not:

class Spinner extends Component {
  render() {
    return "Loading";
  }

  #label() {
    return "Spinner";
  }
}
class Cart {
  formatPrice = cents => "$" + (cents / 100).toFixed(2);
}
class Guest extends User {
  override displayName() {
    return "Guest";
  }
}

With "public-fields", the interface may ask for name(), but it can't ask for the private prefix():

class Guest implements Named {
  name() {
    return "Guest";
  }

  private prefix() {
    return "Mx.";
  }
}