@typescript-eslint/class-methods-use-this
Require class methods to use this
Also called typescript-eslint/class-methods-use-this, typescript/class-methods-use-this
A method that never reads this doesn't need an instance, but callers still have to create one to reach it. Make it static, or move it out of the class.
The rule checks methods, getters, setters, and functions stored in instance fields. It skips constructors, static members, and abstract members.
It's the TypeScript version of class-methods-use-this and reports the same code.
With bunfig.toml you can set either name. bun lint runs this rule in TypeScript files and class-methods-use-this in JavaScript files, so nothing is reported twice. With an ESLint config, turn on only one of the two.
Configure#
Off by default. To turn it on:
[lint.rules]
"@typescript-eslint/class-methods-use-this" = "error" # or "warn"Every option, set to its default:
[lint.rules]
"@typescript-eslint/class-methods-use-this" = ["error", {
exceptMethods = [], # list of strings
enforceForClassFields = true,
ignoreOverrideMethods = false,
# true, false or "public-fields"
ignoreClassesThatImplementAnInterface = false,
}]Examples#
class Invoice {
total = 0;
formatExpected this to be used by class method format.(amount: number) {
return amount.toFixed(2);
}
round = Expected this to be used by class method round.(amount: number) => Math.round(amount);
}class Invoice {
total = 0;
static format(amount: number) {
return amount.toFixed(2);
}
print() {
return Invoice.format(this.total);
}
}Options#
| Option | Default | What it does |
|---|---|---|
exceptMethods | [] | Names of methods to skip. Write a private method as "#name". |
enforceForClassFields | true | Also check functions stored in instance fields, such as round above. |
ignoreOverrideMethods | false | Skip members marked override. |
ignoreClassesThatImplementAnInterface | false | true skips every member of a class that has an implements clause. "public-fields" still checks its private and protected members. |
A subclass must keep the shape of the method it overrides, so it can't make it static:
{ "ignoreOverrideMethods": true }No problemsclass Widget {
name = "widget";
render() {
return this.name;
}
}
class Spinner extends Widget {
override render() {
return "...";
}
}The same goes for a method that an interface requires. With "public-fields", render is skipped and frame is reported. With true, neither is reported.
{ "ignoreClassesThatImplementAnInterface": "public-fields" }1 probleminterface Renderable {
render(): string;
}
class Spinner implements Renderable {
render() {
return "...";
}
private frameExpected this to be used by class method frame.() {
return 0;
}
}