# @typescript-eslint/class-methods-use-this

> Require class methods to 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.

{/* Generated by src/codegen/lint-rule-docs.ts. Do not edit this section. */}

## Configure

Off by default. To turn it on:

```toml bunfig.toml
[lint.rules]
"@typescript-eslint/class-methods-use-this" = "error" # or "warn"
```

Every option, set to its default:

```toml bunfig.toml
[lint.rules]
"@typescript-eslint/class-methods-use-this" = ["error", {
  exceptMethods = [], # list of strings
  enforceForClassFields = true,
  ignoreOverrideMethods = false,
  # true, false or "public-fields"
  ignoreClassesThatImplementAnInterface = false,
}]
```

{/* End of the generated section. */}

## Examples

Reported:

{/* bad {"count": 2} */}
```ts
class Invoice {
  total = 0;

  format(amount: number) {
    return amount.toFixed(2);
  }

  round = (amount: number) => Math.round(amount);
}
```

Not reported:

{/* good */}
```ts
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`:

{/* good {"options": [{"ignoreOverrideMethods": true}]} */}
```ts
class 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.

{/* bad {"options": [{"ignoreClassesThatImplementAnInterface": "public-fields"}], "count": 1} */}
```ts
interface Renderable {
  render(): string;
}

class Spinner implements Renderable {
  render() {
    return "...";
  }
  private frame() {
    return 0;
  }
}
```
