There is no good excuse for an empty class. If it’s being used simply as a common extension point, it should be replaced with an
interface. If it was stubbed in as a placeholder for future development it should be fleshed-out. In any other case, it should be
eliminated.
Additionally, one shouldn’t use a class to define exclusively static methods. Instead one can use a module, or better, export each function separately.
Using an empty class serves no purpose and can hinder the readability of the code.
class Foo {
static bar() {
// ...
}
}
You can export the functions that you wish to make available.
export function bar() {
// ...
}
class Foo { // Noncompliant
static bar() {
// ...
}
}
export function bar() {
// ...
}
class DoAndLog { // Noncompliant
constructor () {
console.log('I\'m done!');
}
}
function doAndLog() {
console.log('I\'m done!');
}
Data containers and value objects whose constructors initialize instance state by assigning properties to this are not flagged. This
includes direct assignments and assignments inside constructor control flow.
class TrieNode { // Compliant
constructor(name, parent) {
this.name = name;
this.parent = parent;
this.children = new Map();
}
}
class PropertyDictionary { // Compliant
constructor(source) {
for (const key in source) {
this[key] = source[key];
}
}
}
Only assignments made directly in the constructor body, or inside its control-flow statements, count as instance initialization. Assignments that occur only inside a nested function or callback body are still reported, because they may execute outside the construction step and therefore do not show that the class establishes its state in the constructor.
class CallbackInit { // Noncompliant
constructor(items) {
items.forEach(item => {
this[item.key] = item.value;
});
}
}