accessor-pairs

Require a getter for every setter in objects and classes

A property with a setter and no getter can be written but never read. user.name = "Ada" works, but user.name is undefined. Most of the time, someone forgot the getter.

The rule looks at object literals, classes, and the descriptors passed to Object.defineProperty(), Object.defineProperties(), Object.create() and Reflect.defineProperty(). A getter without a setter is a read-only property, so it's allowed by default.

Configure#

Off by default. To turn it on:

bunfig.toml
[lint.rules]
"accessor-pairs" = "error" # or "warn"

Every option, set to its default:

bunfig.toml
[lint.rules]
"accessor-pairs" = ["error", {
  setWithoutGet = true,
  getWithoutSet = false,
  enforceForClassMembers = true,
  enforceForTSTypes = false,
}]

Examples#

example.js1 problem
const user = {
  set name(value) {
    this._name = value.trim();
  },
};
example.js1 problem
Object.defineProperty(user, "name", {
  set(value) {
    this._name = value.trim();
  },
});
example.jsNo problems
const user = {
  get name() {
    return this._name;
  },
  set name(value) {
    this._name = value.trim();
  },
};

const config = {
  get version() {
    return 3;
  },
};

Options#

OptionDefaultWhat it does
setWithoutGettrueReport a setter that has no getter.
getWithoutSetfalseReport a getter that has no setter.
enforceForClassMemberstrueAlso check classes. A static accessor only pairs with a static one.
enforceForTSTypesfalseAlso check TypeScript interfaces and object types.
example.jswith { "getWithoutSet": true }1 problem
const config = {
  get version() {
    return 3;
  },
};
example.jswith { "enforceForClassMembers": false }No problems
class User {
  set name(value) {
    this._name = value.trim();
  }
}
example.tswith { "enforceForTSTypes": true }1 problem
interface User {
  set name(value: string);
}