mirror of
https://git.proxmox.com/git/pve-eslint
synced 2025-10-29 18:10:26 +00:00
includes a (minimal) working wrapper Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
290 lines
6.3 KiB
Markdown
290 lines
6.3 KiB
Markdown
# Enforces getter/setter pairs in objects and classes (accessor-pairs)
|
|
|
|
It's a common mistake in JavaScript to create an object with just a setter for a property but never have a corresponding getter defined for it. Without a getter, you cannot read the property, so it ends up not being used.
|
|
|
|
Here are some examples:
|
|
|
|
```js
|
|
// Bad
|
|
var o = {
|
|
set a(value) {
|
|
this.val = value;
|
|
}
|
|
};
|
|
|
|
// Good
|
|
var o = {
|
|
set a(value) {
|
|
this.val = value;
|
|
},
|
|
get a() {
|
|
return this.val;
|
|
}
|
|
};
|
|
|
|
```
|
|
|
|
This rule warns if setters are defined without getters. Using an option `getWithoutSet`, it will warn if you have a getter without a setter also.
|
|
|
|
## Rule Details
|
|
|
|
This rule enforces a style where it requires to have a getter for every property which has a setter defined.
|
|
|
|
By activating the option `getWithoutSet` it enforces the presence of a setter for every property which has a getter defined.
|
|
|
|
This rule always checks object literals and property descriptors. By default, it also checks class declarations and class expressions.
|
|
|
|
## Options
|
|
|
|
* `setWithoutGet` set to `true` will warn for setters without getters (Default `true`).
|
|
* `getWithoutSet` set to `true` will warn for getters without setters (Default `false`).
|
|
* `enforceForClassMembers` set to `true` additionally applies this rule to class getters/setters (Default `true`). Set `enforceForClassMembers` to `false` if you want this rule to ignore class declarations and class expressions.
|
|
|
|
### setWithoutGet
|
|
|
|
Examples of **incorrect** code for the default `{ "setWithoutGet": true }` option:
|
|
|
|
```js
|
|
/*eslint accessor-pairs: "error"*/
|
|
|
|
var o = {
|
|
set a(value) {
|
|
this.val = value;
|
|
}
|
|
};
|
|
|
|
var o = {d: 1};
|
|
Object.defineProperty(o, 'c', {
|
|
set: function(value) {
|
|
this.val = value;
|
|
}
|
|
});
|
|
```
|
|
|
|
Examples of **correct** code for the default `{ "setWithoutGet": true }` option:
|
|
|
|
```js
|
|
/*eslint accessor-pairs: "error"*/
|
|
|
|
var o = {
|
|
set a(value) {
|
|
this.val = value;
|
|
},
|
|
get a() {
|
|
return this.val;
|
|
}
|
|
};
|
|
|
|
var o = {d: 1};
|
|
Object.defineProperty(o, 'c', {
|
|
set: function(value) {
|
|
this.val = value;
|
|
},
|
|
get: function() {
|
|
return this.val;
|
|
}
|
|
});
|
|
|
|
```
|
|
|
|
### getWithoutSet
|
|
|
|
Examples of **incorrect** code for the `{ "getWithoutSet": true }` option:
|
|
|
|
```js
|
|
/*eslint accessor-pairs: ["error", { "getWithoutSet": true }]*/
|
|
|
|
var o = {
|
|
set a(value) {
|
|
this.val = value;
|
|
}
|
|
};
|
|
|
|
var o = {
|
|
get a() {
|
|
return this.val;
|
|
}
|
|
};
|
|
|
|
var o = {d: 1};
|
|
Object.defineProperty(o, 'c', {
|
|
set: function(value) {
|
|
this.val = value;
|
|
}
|
|
});
|
|
|
|
var o = {d: 1};
|
|
Object.defineProperty(o, 'c', {
|
|
get: function() {
|
|
return this.val;
|
|
}
|
|
});
|
|
```
|
|
|
|
Examples of **correct** code for the `{ "getWithoutSet": true }` option:
|
|
|
|
```js
|
|
/*eslint accessor-pairs: ["error", { "getWithoutSet": true }]*/
|
|
var o = {
|
|
set a(value) {
|
|
this.val = value;
|
|
},
|
|
get a() {
|
|
return this.val;
|
|
}
|
|
};
|
|
|
|
var o = {d: 1};
|
|
Object.defineProperty(o, 'c', {
|
|
set: function(value) {
|
|
this.val = value;
|
|
},
|
|
get: function() {
|
|
return this.val;
|
|
}
|
|
});
|
|
|
|
```
|
|
|
|
### enforceForClassMembers
|
|
|
|
When `enforceForClassMembers` is set to `true` (default):
|
|
|
|
* `"getWithoutSet": true` will also warn for getters without setters in classes.
|
|
* `"setWithoutGet": true` will also warn for setters without getters in classes.
|
|
|
|
Examples of **incorrect** code for `{ "getWithoutSet": true, "enforceForClassMembers": true }`:
|
|
|
|
```js
|
|
/*eslint accessor-pairs: ["error", { "getWithoutSet": true, "enforceForClassMembers": true }]*/
|
|
|
|
class Foo {
|
|
get a() {
|
|
return this.val;
|
|
}
|
|
}
|
|
|
|
class Bar {
|
|
static get a() {
|
|
return this.val;
|
|
}
|
|
}
|
|
|
|
const Baz = class {
|
|
get a() {
|
|
return this.val;
|
|
}
|
|
static set a(value) {
|
|
this.val = value;
|
|
}
|
|
}
|
|
```
|
|
|
|
Examples of **incorrect** code for `{ "setWithoutGet": true, "enforceForClassMembers": true }`:
|
|
|
|
```js
|
|
/*eslint accessor-pairs: ["error", { "setWithoutGet": true, "enforceForClassMembers": true }]*/
|
|
|
|
class Foo {
|
|
set a(value) {
|
|
this.val = value;
|
|
}
|
|
}
|
|
|
|
const Bar = class {
|
|
static set a(value) {
|
|
this.val = value;
|
|
}
|
|
}
|
|
```
|
|
|
|
When `enforceForClassMembers` is set to `false`, this rule ignores classes.
|
|
|
|
Examples of **correct** code for `{ "getWithoutSet": true, "setWithoutGet": true, "enforceForClassMembers": false }`:
|
|
|
|
```js
|
|
/*eslint accessor-pairs: ["error", {
|
|
"getWithoutSet": true, "setWithoutGet": true, "enforceForClassMembers": false
|
|
}]*/
|
|
|
|
class Foo {
|
|
get a() {
|
|
return this.val;
|
|
}
|
|
}
|
|
|
|
class Bar {
|
|
static set a(value) {
|
|
this.val = value;
|
|
}
|
|
}
|
|
|
|
const Baz = class {
|
|
static get a() {
|
|
return this.val;
|
|
}
|
|
}
|
|
|
|
const Quux = class {
|
|
set a(value) {
|
|
this.val = value;
|
|
}
|
|
}
|
|
```
|
|
|
|
|
|
## Known Limitations
|
|
|
|
Due to the limits of static analysis, this rule does not account for possible side effects and in certain cases
|
|
might not report a missing pair for a getter/setter that has a computed key, like in the following example:
|
|
|
|
```js
|
|
/*eslint accessor-pairs: "error"*/
|
|
|
|
var a = 1;
|
|
|
|
// no warnings
|
|
var o = {
|
|
get [a++]() {
|
|
return this.val;
|
|
},
|
|
set [a++](value) {
|
|
this.val = value;
|
|
}
|
|
};
|
|
```
|
|
|
|
Also, this rule does not disallow duplicate keys in object literals and class definitions, and in certain cases with duplicate keys
|
|
might not report a missing pair for a getter/setter, like in the following example:
|
|
|
|
```js
|
|
/*eslint accessor-pairs: "error"*/
|
|
|
|
// no warnings
|
|
var o = {
|
|
get a() {
|
|
return this.val;
|
|
},
|
|
a: 1,
|
|
set a(value) {
|
|
this.val = value;
|
|
}
|
|
};
|
|
```
|
|
|
|
The code above creates an object with just a setter for the property `"a"`.
|
|
|
|
See [no-dupe-keys](no-dupe-keys.md) if you also want to disallow duplicate keys in object literals.
|
|
|
|
See [no-dupe-class-members](no-dupe-class-members.md) if you also want to disallow duplicate names in class definitions.
|
|
|
|
## When Not To Use It
|
|
|
|
You can turn this rule off if you are not concerned with the simultaneous presence of setters and getters on objects.
|
|
|
|
## Further Reading
|
|
|
|
* [Object Setters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set)
|
|
* [Object Getters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get)
|
|
* [Working with Objects](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects)
|