Skip to content

Latest commit

 

History

History
81 lines (58 loc) · 3.75 KB

no-unused-properties.md

File metadata and controls

81 lines (58 loc) · 3.75 KB

Disallow unused object properties

Unused properties, much like unused variables, are often a result of incomplete refactoring and may confuse readers.

This rule is primarily useful when you use objects to group constants or model enumerations. It is much harder to predict class properties usage, and practically impossible to predict reflective property access. This rule ignores cases like that.

Example use cases

When using React's inline styles or one of many CSS-in-JS like glamor, one might find it helpful to group component styles into a constant object. Later you might remove one of the styles, but forget to remove its definition, especially if the component grew in complexity by that time. If these were defined as separate constants, ESLint's builtin no-unused-vars rule would have helped, but they are not. That's when the no-unused-properties rules becomes useful.

const styles = {
	success: {},
	danger: {} // <- Property `danger` is defined but never used
};

export default () => r.div({style: styles.success});

This issue extends to most enumeration and const-like use cases. Below is an example straight from Bootstrap's scrollspy. The file contains about 300 lines of DOM/jQuery complexity. It's practically impossible to notice the issue manually. But this extra property indicates that authors intended but forgot to handle dropdown menus specially, or at least have a useless constant defined.

const ClassName = {
	DROPDOWN_ITEM: 'dropdown-item',
	DROPDOWN_MENU: 'dropdown-menu', // <- Property `DROPDOWN_MENU` is defined but never used
	ACTIVE: 'active'
};

Fail

const enum = {
	used: 1,
	unused: 2 // <- Property `unused` is defined but never used.
};

console.log(enum.used);

const {used} = enum;

Pass

const enum = {
	used: 1,
	usedToo: 2
};

console.log(enum); // The whole object is used

console.log(enum.used, enum.usedToo); // Every property is used individually

enum[x] // Unpredictable, all properties are considered to be used

// Objects with methods are skipped too, all properties are considered used
const foo = {
	used: 1,
	method() {
		return this;
	}
};

Scope and limitations

This rule tries hard not to report potentially used properties as unused. Basically, all supported use cases are enum-like as shown above, more complex cases are ignored. Detailed list of limitations follows.

  • Does not predict dynamic property access. That is, object[keys] says that all properties of an object are potentially used. This is as unpredictable for this rule as eval(...) is for the no-unused-vars rule.
  • Same goes for computed property keys in object definitions, like {[key]: value}.
  • If a variable is unused, it is not checked. This is done to play nicely with the no-unused-vars rule, which everybody should have enabled at all times.
  • Does not check objects used as an argument. If you call f(object), it behaves like you used all of its properties, since it's hard to predict what a function would do with the object.
  • If you call a method on an object, it is ignored. Because of this, it's basically the same as calling a function on an object.
  • If you assign to an object, it is ignored. Even if the key you assign to is static.
  • Classes are not checked.
  • Prototypes are not checked. Only own properties are.
  • Does not follow objects across files. If you export an object, it's like if you used all of its properties.

If you want to lift some of these limitations, you should try tools like Flow or TypeScript.