
Security News
ECMAScript 2025 Finalized with Iterator Helpers, Set Methods, RegExp.escape, and More
ECMAScript 2025 introduces Iterator Helpers, Set methods, JSON modules, and more in its latest spec update approved by Ecma in June 2025.
@odg/eslint-config
Advanced tools
Add dependence to package.json
npm install eslint @odg/eslint-config
# or
yarn add -D eslint @odg/eslint-config
Add extends in your .eslintrc
file
{
"extends": [ "@odg" ]
}
Add script in your package.json
file
{
"scripts": {
"lint": "eslint --ext .js,.jsx,.ts,.tsx,.json,.jsonc,.json5,.yml,.yaml,.xml,.txt,.svg,.properties,.gradle,.java,.cpp,.c,.cs,.html,.css,.groovy,.gitignore,.npmignore,.toml,.env,.example,.sample,.ini,.php,.bat,.powershell,.ps1,.sh,.bash,.eslintrc",
}
}
Test: npm run lint
or yarn lint
File Name Convention
https://github.com/selaux/eslint-plugin-filenames
π Examples of correct code
// File name Foo.ts
export default class Foo {
}
π Examples of incorrect code
// File name FooClass.ts
export default class Foo {
}
Requires semicolons at the end of statements
https://eslint.org/docs/rules/semi#semi https://eslint.org/docs/rules/semi-style
π Examples of correct code
var name = "ODG";
object.method = function() {
// ...
};
class Foo {
bar = 1;
}
foo();
[1, 2, 3].forEach(bar);
for (
var i = 0;
i < 10;
++i
) {
foo();
}
class C {
static {
foo();
}
}
π Examples of incorrect code
var name = "ODG"
object.method = function() {
// ...
}
class Foo {
bar = 1
}
foo()
;[1, 2, 3].forEach(bar)
for (
var i = 0
; i < 10
; ++i
) {
foo()
}
class C {
static {
foo()
;bar()
}
}
Requires the use of double quotes wherever possible
Enforces the use of double quotes for all JSX attribute values that donβt contain a double quote.
https://eslint.org/docs/rules/quotes https://eslint.org/docs/rules/jsx-quotes
π Examples of correct code
var double = "double";
var backtick = `back
tick`; // backticks are allowed due to newline
var backtick = tag`backtick`;
π Examples of incorrect code
var single = 'single';
var unescaped = 'a string containing "double" quotes';
var backtick = `back\ntick`; // you can use \n in single or double quoted strings
Requires indent with 4 spaces Tabs Disallow
https://eslint.org/docs/rules/indent#indent https://sonarsource.github.io/rspec/#/rspec/S3973/javascript https://eslint.org/docs/latest/rules/no-tabs https://eslint.org/docs/latest/rules/no-mixed-spaces-and-tabs
π Examples of correct code
if (a) {
b=c;
function foo(d) {
e=f;
}
}
π Examples of incorrect code
if (a) {
b=c;
function foo(d) {
e=f;
}
}
Enforces the usage of Unix line endings: \n
for LF.
https://eslint.org/docs/rules/linebreak-style#linebreak-style
π Examples of correct code
var a = 'a'; // \n
π Examples of incorrect code
var a = 'a'; // \r\n
Force empty end line
https://eslint.org/docs/rules/eol-last#eol-last
π Examples of correct code
function doSmth() {
var foo = 2;
} // \n
π Examples of incorrect code
function doSmth() {
var foo = 2;
}
Max line len is 120
https://eslint.org/docs/rules/max-len#max-len
π Examples of correct code
var foo = {
"bar": "This is a bar.",
"baz": { "qux": "This is a qux" },
"difficult": "to read",
};
π Examples of incorrect code
var foo = { "bar": "This is a bar.", "baz": { "qux": "This is a qux" }, "difficult": "to read" };
Force use camel case variable
https://eslint.org/docs/rules/camelcase#camelcase
π Examples of correct code
import { no_camelcased as camelCased } from "external-module";
var myFavoriteColor = "#112C85";
var _myFavoriteColor = "#112C85";
var myFavoriteColor_ = "#112C85";
var MY_FAVORITE_COLOR = "#112C85";
π Examples of incorrect code
import { no_camelcased } from "external-module"
var my_favorite_color = "#112C85";
function do_something() {
// ...
}
A strict mode directive is a "use strict" literal at the beginning of a script or function body. It enables strict mode semantics.
https://eslint.org/docs/latest/rules/strict
π Examples of correct code
"use strict";
function foo() {
}
π Examples of incorrect code
function foo() {
}
force empty line in blocks
https://eslint.org/docs/rules/padded-blocks#padded-blocks
{
"classes": "always",
"blocks": "never",
"switches": "never",
}
π Examples of correct code
class ClassName {
variable = 1;
}
switch (a) {
case 0: foo();
}
if (a) {
a = b;
}
π Examples of incorrect code
class ClassName {
variable = 1;
}
class ClassName {
variable = 1;
}
switch (a) {
case 0: foo();
}
if (a) {
a = b;
}
Enforces consistent spacing before function parenthesis.
https://eslint.org/docs/rules/lines-between-class-members#lines-between-class-members https://eslint.style/rules/ts/lines-between-class-members
π Examples of correct code
class MyClass {
x;
foo() {
//...
}
bar() {
//...
}
}
π Examples of incorrect code
class MyClass {
x;
foo() {
//...
}
bar() {
//...
}
}
Chaining the assignment of variables can lead to unexpected results and be difficult to read. Disabled.
https://eslint.org/docs/rules/no-multi-assign#no-multi-assign
π Examples of correct code
var a = 5;
var b = 5;
var c = 5;
const foo = "baz";
const bar = "baz";
let a = c;
let b = c;
class Foo {
a = 10;
b = 10;
}
a = "quux";
b = "quux";
π Examples of incorrect code
var a = b = c = 5;
const foo = bar = "baz";
let a =
b =
c;
class Foo {
a = b = 10;
}
a = b = "quux";
Force specific public/private or protected visibility
{
"anonymous": "never",
"named": "never",
"asyncArrow": "always"
}
π Examples of correct code
class ClassName {
public a = 1;
protected c = 2;
private b = 3;
}
π Examples of incorrect code
class ClassName {
a = 1;
c = 2;
b = 3;
}
Enforces default parameters to be last.
https://eslint.org/docs/rules/default-param-last#default-param-last
π Examples of correct code
function f(a = 0) {}
function f(a: number, b = 0) {}
function f(a: number, b?: number) {}
function f(a: number, b?: number, c = 0) {}
function f(a: number, b = 0, c?: number) {}
class Foo {
constructor(public a, private b = 0) {}
}
class Foo {
constructor(public a, private b?: number) {}
}
π Examples of incorrect code
function f(a = 0, b: number) {}
function f(a: number, b = 0, c: number) {}
function f(a: number, b?: number, c: number) {}
class Foo {
constructor(public a = 10, private b: number) {}
}
class Foo {
constructor(public a?: number, private b: number) {}
}
Enforces default parameters to be last.
https://eslint.org/docs/latest/rules/space-before-function-paren https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/space-before-function-paren.md https://eslint.style/rules/ts/space-before-function-paren
π Examples of correct code
foo(function() {
})
function foo() {
}
(async () => {})()
π Examples of incorrect code
foo(function () {
})
function foo () {
}
(async() => {})()
Enforces callback error handling.
https://eslint.org/docs/rules/handle-callback-err https://github.com/weiran-zsd/eslint-plugin-node/blob/HEAD/docs/rules/handle-callback-err.md
π Examples of correct code
function loadData (err, data) {
if (err) {
console.log(err.stack);
}
doSomething();
}
function loadData (exception, data) {
if (exception) {
console.log(exception);
}
doSomething();
}
function generateError (err) {
if (err) {
throw new Exception(err.message);
}
}
π Examples of incorrect code
function loadData (err, data) {
doSomething();
}
function loadData (exception, data) {
doSomething();
}
This rule requires constructor names to begin with a capital letter.
https://eslint.org/docs/rules/new-cap
π Examples of correct code
var friend = new Person();
π Examples of incorrect code
var friend = new person();
var friend = Person();
requires one or more spaces or newlines inside array brackets, and disallow space inside of computed properties.
https://eslint.org/docs/rules/array-bracket-spacing#array-bracket-spacing
https://eslint.org/docs/rules/computed-property-spacing#computed-property-spacing
π Examples of correct code
var arr = [ 'foo', 'bar' ];
var [ x, y ] = z;
var c = arr[0];
π Examples of incorrect code
var arr = ['foo', 'bar'];
var [x,y] = z;
var c = arr[ 0 ];
var c = object[ "foo" ];
var c = object["foo" ];
var c = object[ "foo"];
Enforces consistent spacing before and after keywords.
https://eslint.org/docs/rules/keyword-spacing#keyword-spacing https://eslint.org/docs/rules/yield-star-spacing https://eslint.style/rules/ts/keyword-spacing
π Examples of correct code
if (foo) {
//...
} else if (bar) {
//...
} else {
//...
}
try {
} catch(e) {
// code ...
}
function *generator() {
yield *other();
}
π Examples of incorrect code
if(foo){
//...
}else if(bar){
//...
}else{
//...
}
try{
}catch(e){
// code ...
}
function*generator() {
yield*other();
}
function* generator() {
yield* other();
}
function * generator() {
yield * other();
}
This rule enforces consistency regarding the spaces after
https://eslint.org/docs/rules/space-unary-ops#space-unary-ops
π Examples of correct code
a++;
++a;
--a;
a--;
async function foo() {
await bar;
}
if (!foo) {
}
const value = +"3";
π Examples of incorrect code
a ++;
++ a;
-- a;
a --;
async function foo() {
await(bar);
}
if (! foo) {
}
const value = + "3";
Disallow the Unicode Byte Order Mark (BOM).
https://eslint.org/docs/rules/unicode-bom#unicode-bom
Disallows or enforce spaces inside of parentheses.
https://eslint.org/docs/rules/space-in-parens#space-in-parens
π Examples of correct code
foo();
foo('bar');
foo(/* bar */);
var foo = (1 + 2) * 3;
(function () { return 'bar'; }());
π Examples of incorrect code
foo( );
foo( 'bar');
foo('bar' );
foo( 'bar' );
foo( /* bar */ );
var foo = ( 1 + 2 ) * 3;
( function () { return 'bar'; }() );
Disallows multiple consecutive spaces.
https://eslint.org/docs/rules/no-multi-spaces#no-multi-spaces
π Examples of correct code
var a = 1;
if(foo === "bar") {}
a << b
var arr = [ 1, 2 ];
var a = [];
var baz = [];
a ? b : c
π Examples of incorrect code
var a = 1;
if(foo === "bar") {}
a << b
var arr = [1, 2];
var c = [];
var baz = [];
a ? b : c
Disallows useless string concat.
https://eslint.org/docs/rules/no-useless-concat#no-useless-concat
π Examples of correct code
var c = a + b;
var c = '1' + a;
var a = 1 + '1';
var c = 1 - 2;
// when the string concatenation is multiline
var c = "foo" +
"bar";
π Examples of incorrect code
var a = `some` + `string`;
// these are the same as "10"
var a = '1' + '0';
var a = '1' + `0`;
var a = `1` + '0';
var a = `1` + `0`;
Disallows assignments where both sides are exactly the same.
https://eslint.org/docs/rules/no-self-assign#no-self-assign
π Examples of correct code
foo = bar;
[a, b] = [b, a];
// This pattern is warned by the `no-use-before-define` rule.
let foo = foo;
// The default values have an effect.
[foo = 1] = [foo];
// non-self-assignments with properties.
obj.a = obj.b;
obj.a.b = obj.c.b;
obj.a.b = obj.a.c;
obj[a] = obj["a"];
π Examples of incorrect code
foo = foo;
[a, b] = [a, b];
[a, ...b] = [x, ...b];
({a, b} = {a, x});
foo &&= foo;
foo ||= foo;
foo ??= foo;
Force fill return type in typescript
π Examples of correct code
function test(): void {
return;
}
// A return value of type number
var fn = function (): number {
return 1;
};
// A return value of type string
var arrowFn = (): string => 'test';
class Test {
// No return value should be expected (void)
method(): void {
return;
}
}
π Examples of incorrect code
function test() {
return;
}
// Should indicate that a number is returned
var fn = function () {
return 1;
};
// Should indicate that a string is returned
var arrowFn = () => 'test';
class Test {
// Should indicate that no value is returned (void)
method() {
return;
}
}
Requires consistent usage of linebreaks for each pair of brackets. It reports an error if one bracket in the pair has a linebreak inside it and the other bracket does not.
https://eslint.org/docs/rules/array-bracket-newline#consistent
π Examples of correct code
var a = [];
var c = [ 1 ];
var d = [
1
];
var f = [
function foo() {
dosomething();
}
];
π Examples of incorrect code
var a = [1
];
var b = [
1];
var c = [function foo() {
dosomething();
}
]
var d = [
function foo() {
dosomething();
}]
Variables that are declared and not used anywhere in the code are most likely an error due to incomplete refactoring. Such variables take up space in the code and can lead to confusion by readers.
https://eslint.org/docs/rules/no-unused-vars#no-unused-vars
π Examples of correct code
var x = 10;
alert(x);
// foo is considered used here
myFunc(function foo() {
// ...
}.bind(this));
(function(foo) {
return foo;
})();
var myFunc;
myFunc = setTimeout(function() {
// myFunc is considered used
myFunc();
}, 50);
// Only the second argument from the destructured array is used.
function getY([, y]) {
return y;
}
π Examples of incorrect code
// It checks variables you have defined as global
some_unused_var = 42;
var x;
// Write-only variables are not considered as used.
var y = 10;
y = 5;
// A read for a modification of itself is not considered as used.
var z = 0;
z = z + 1;
// By default, unused arguments cause warnings.
(function(foo) {
return 5;
})();
// Unused recursive functions also cause warnings.
function fact(n) {
if (n < 2) return 1;
return n * fact(n - 1);
}
// When a function definition destructures an array, unused entries from the array also cause warnings.
function getY([x, y]) {
return y;
}
Putting default parameter at last allows function calls to omit optional tail arguments.
https://eslint.org/docs/rules/comma-spacing#options https://eslint.style/rules/ts/comma-spacing
π Examples of correct code
var foo = 1, bar = 2
, baz = 3;
var arr = [1, 2];
var arr = [1,, 3]
var obj = {"foo": "bar", "baz": "qur"};
foo(a, b);
new Foo(a, b);
function foo(a, b){}
a, b
π Examples of incorrect code
var foo = 1 ,bar = 2;
var arr = [1 , 2];
var obj = {"foo": "bar" ,"baz": "qur"};
foo(a ,b);
new Foo(a ,b);
function foo(a ,b){}
a ,b
This rule enforces consistent use of trailing commas in object and array literals.
https://eslint.org/docs/rules/comma-dangle#comma-dangle https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/comma-dangle.md https://eslint.style/rules/ts/comma-dangle
π Examples of correct code
var foo = {
bar: "baz",
qux: "quux",
bar: "baz",
};
function baz(
a,
b,
c,
) {
// code ...
}
π Examples of incorrect code
var foo = {
bar: "baz",
qux: "quux",
bar: "baz"
};
function baz(
a,
b,
c
) {
// code ...
}
This rule normalize style of spacing before/after an arrow functionβs arrow(=>).
https://eslint.org/docs/latest/rules/arrow-spacing
π Examples of correct code
() => {};
(a) => {};
() => {'\n'};
π Examples of incorrect code
()=> {};
() =>{};
(a)=> {};
(a) =>{};
a =>a;
a=> a;
()=> {'\n'};
() =>{'\n'};
Requires using arrow functions for callbacks.
https://eslint.org/docs/rules/prefer-arrow-callback#prefer-arrow-callback
π Examples of correct code
foo(a => a);
foo(() => this.a);
foo(function*() { yield; });
π Examples of incorrect code
foo(function(a) { return a; });
foo(function() { return this.a; }.bind(this));
Require destructuring from arrays and/or objects
https://eslint.org/docs/latest/rules/prefer-destructuring https://sonarsource.github.io/rspec/#/rspec/S3514/javascript
π Examples of correct code
var [ foo ] = array;
var foo = array[someIndex];
var { foo } = object;
var foo = object.bar;
let foo;
({ foo } = object);
π Examples of incorrect code
// With `array` enabled
var foo = array[0];
// With `object` enabled
var foo = object.foo;
var foo = object['foo'];
Enforces no braces where they can be omitted
https://eslint.org/docs/rules/arrow-body-style#arrow-body-style
π Examples of correct code
() => {};
(a) => {};
(a) => a;
(a) => {'\n'}
a.then((foo) => {});
a.then((foo) => { if (true) {} });
π Examples of incorrect code
a => {};
a => a;
a => {'\n'};
a.then(foo => {});
a.then(foo => a);
a(foo => { if (true) {} });
Enforces parentheses around arguments in all cases.
https://eslint.org/docs/rules/arrow-parens
π Examples of correct code
let foo = () => 0;
let foo = (retv, name) => {
retv[name] = true;
return retv;
};
let foo = () => ({
bar: {
foo: 1,
bar: 2,
}
});
let foo = () => { bar(); };
let foo = () => {};
let foo = () => { /* do nothing */ };
let foo = () => {
// do nothing.
};
let foo = () => ({ bar: 0 });
π Examples of incorrect code
let foo = () => {
return 0;
};
let foo = () => {
return {
bar: {
foo: 1,
bar: 2,
}
};
};
Enforces parentheses around arguments in all cases.
https://eslint.org/docs/rules/arrow-parens
π Examples of correct code
(foo) => bar;
(foo) => (bar);
(foo) => bar => baz;
(foo) => (
bar()
);
// functions with block bodies allowed with this rule using any style
// to enforce a consistent location for this case, see the rule: `brace-style`
(foo) => {
return bar();
}
(foo) =>
{
return bar();
}
π Examples of incorrect code
(foo) =>
bar;
(foo) =>
(bar);
(foo) =>
bar =>
baz;
(foo) =>
(
bar()
);
Disallows empty block statements.
https://eslint.org/docs/rules/no-empty#no-empty
π Examples of correct code
if (!foo) {
// code
}
while (foo) {
// code
}
try {
doSomething();
} catch (ex) {
// continue regardless of error
}
try {
doSomething();
} finally {
/* continue regardless of error */
}
π Examples of incorrect code
if (foo) {
} else {
// code
}
while (foo) {
}
switch(foo) {
}
try {
doSomething();
} catch(ex) {
} finally {
}
Disallow Array constructors
https://eslint.org/docs/latest/rules/no-array-constructor
π Examples of correct code
const arr: Array<number> = [ 1, 2, 3 ];
const arr: Array<Foo> = [ x, y, z ];
Array(500);
new Array(someOtherArray.length);
π Examples of incorrect code
const arr = Array(0, 1, 2);
const arr = new Array(0, 1, 2);
Disallows unnecessary parentheses.
https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/no-extra-parens.md https://eslint.org/docs/rules/no-extra-parens#no-extra-parens https://eslint.style/rules/ts/no-extra-parens
π Examples of correct code
a = (b * c);
(a * b) + c;
for (a in (b, c));
for (a in (b));
for (a of (b));
typeof (a);
(function(){} ? a() : b());
class A {
[(x)] = 1;
}
class B {
x = (y + z);
}
π Examples of incorrect code
a = (b * c);
(a * b) + c;
for (a in (b, c));
for (a in (b));
for (a of (b));
typeof (a);
(function(){} ? a() : b());
class A {
[(x)] = 1;
}
class B {
x = (y + z);
}
Disallow useless code
https://eslint.org/docs/rules/no-useless-constructor#options
π Examples of correct code
var foo = !!bar;
var foo = Boolean(bar);
function foo() {
return !!bar;
}
var foo = bar ? !!baz : !!bat;
π Examples of incorrect code
var foo = !!!bar;
var foo = !!bar ? baz : bat;
var foo = Boolean(!!bar);
var foo = new Boolean(!!bar);
if (!!foo) {
// ...
}
if (Boolean(foo)) {
// ...
}
while (!!foo) {
// ...
}
do {
// ...
} while (Boolean(foo));
for ( ;!!foo; ) {
// ...
}
Disallows renaming import, export, and destructured assignments to the same name.
https://eslint.org/docs/rules/no-useless-rename
π Examples of correct code
import * as foo from "foo";
import { foo } from "bar";
import { foo as bar } from "baz";
import { "foo" as bar } from "baz";
export { foo };
export { foo as bar };
export { foo as bar } from "foo";
let { foo } = bar;
let { foo: bar } = baz;
let { [foo]: foo } = bar;
function foo({ bar }) {}
function foo({ bar: baz }) {}
({ foo }) => {}
({ foo: bar }) => {}
π Examples of incorrect code
import { foo as foo } from "bar";
import { "foo" as foo } from "bar";
export { foo as foo };
export { foo as "foo" };
export { foo as foo } from "bar";
export { "foo" as "foo" } from "bar";
let { foo: foo } = bar;
let { 'foo': foo } = bar;
function foo({ bar: bar }) {}
({ foo: foo }) => {}
Force new line before return
https://eslint.org/docs/rules/newline-before-return#newline-before-return
π Examples of correct code
function foo(bar) {
var baz = 'baz';
if (bar()) {
return true;
}
if (!bar) {
bar = baz;
return baz;
}
return bar;
}
π Examples of incorrect code
function foo(bar) {
var baz = 'baz';
if (bar()) {
return true;
}
if (!bar) {
bar = baz;
return bar;
}
return bar;
}
Prefer Multi-line comment formated
https://eslint.org/docs/rules/newline-before-return#newline-before-return
π Examples of correct code
/*
* this line
* calls foo()
*/
foo();
// single-line comment
π Examples of incorrect code
// this line
// calls foo()
foo();
/* this line
calls foo() */
foo();
/* this comment
* is missing a newline after /*
*/
/*
* this comment
* is missing a newline at the end */
/*
* the star in this line should have a space before it
*/
/*
* the star on the following line should have a space before it
*/
Create custom class to Throw
https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/no-throw-literal.md https://eslint.org/docs/rules/prefer-promise-reject-errors#prefer-promise-reject-errors
π Examples of correct code
class CustomError extends Error {
// ...
};
const e = new CustomError("error");
throw e;
throw new CustomError("error");
function err() {
return new CustomError();
}
throw err();
const foo = {
bar: new CustomError();
}
throw foo.bar;
// promises
Promise.reject(new CustomError("something bad happened"));
Promise.reject(new TypeError("something bad happened"));
new Promise(function(resolve, reject) {
reject(new CustomError("something bad happened"));
});
var foo = getUnknownValue();
Promise.reject(foo);
π Examples of incorrect code
throw new Error();
throw 'error';
throw 0;
throw undefined;
throw null;
const err = new Error();
throw 'an ' + err;
const err = new Error();
throw `${err}`;
const err = '';
throw err;
function err() {
return '';
}
throw err();
const foo = {
bar: '',
};
throw foo.bar;
// Promise
Promise.reject("something bad happened");
Promise.reject(5);
Promise.reject();
new Promise(function(resolve, reject) {
reject("something bad happened");
});
new Promise(function(resolve, reject) {
reject();
});
No Unreachable code
https://eslint.org/docs/rules/no-unreachable https://sonarsource.github.io/rspec/#/rspec/S6079/javascript
π Examples of correct code
function foo() {
function bar() {
return 1;
}
return bar();
}
function bar() {
var x;
return x;
}
switch (foo) {
case 1:
break;
}
π Examples of incorrect code
function foo() {
return true;
console.log("done");
}
function bar() {
throw new Error("Oops!");
console.log("done");
}
while(value) {
break;
console.log("done");
}
throw new Error("Oops!");
console.log("done");
function baz() {
if (Math.random() < 0.5) {
return;
} else {
throw new Error();
}
console.log("done");
}
for (;;) {}
console.log("done");
Prevent break line in string
https://eslint.org/docs/rules/no-multi-str#no-multi-str
π Examples of correct code
var x = "some very\nlong text";
var x = "some very " +
"long text";
π Examples of incorrect code
var x = "some very \
long text";
Disallows assigning any to variables and properties.
π Examples of correct code
const x = 1,
y = 1;
const [x] = [1];
[x] = [1] as [number];
function foo(a = 1) {}
class Foo {
constructor(private a = 1) {}
}
class Foo {
private a = 1;
}
// generic position examples
const x: Set<string> = new Set<string>();
const x: Map<string, string> = new Map<string, string>();
const x: Set<string[]> = new Set<string[]>();
const x: Set<Set<Set<string>>> = new Set<Set<Set<string>>>();
π Examples of incorrect code
const x = 1 as any,
y = 1 as any;
const [x] = 1 as any;
const [x] = [] as any[];
const [x] = [1 as any];
[x] = [1] as [any];
function foo(a = 1 as any) {}
class Foo {
constructor(private a = 1 as any) {}
}
class Foo {
private a = 1 as any;
}
// generic position examples
const x: Set<string> = new Set<any>();
const x: Map<string, string> = new Map<string, any>();
const x: Set<string[]> = new Set<any[]>();
const x: Set<Set<Set<string>>> = new Set<Set<Set<any>>>();
Using javascript: URLs is considered by some as a form of eval.
https://eslint.org/docs/rules/no-script-url
π Examples of correct code
location.href = "#";
π Examples of incorrect code
location.href = "javascript:void(0)";
location.href = `javascript:void(0)`;
Disallows the use of undeclared variables unless mentioned in /*global*/ comments.
https://eslint.org/docs/rules/no-undef
π Examples of correct code
/* global someFunction, a */
var foo = someFunction();
var bar = a + 1;
π Examples of incorrect code
var foo = someFunction();
var bar = a + 1;
Requires function expressions to have a name, if the name isn't assigned automatically per the ECMAScript specification.
https://eslint.org/docs/rules/func-names https://sonarsource.github.io/rspec/#/rspec/S100/javascript
π Examples of correct code
/* global someFunction, a */
var foo = someFunction();
var bar = a + 1;
π Examples of incorrect code
Foo.prototype.bar = function() {};
(function() {
// ...
}())
export default function() {}
This rule requires function names to match the name of the variable or property to which they are assigned. The rule will ignore property assignments where the property name is a literal that is not a valid identifier in the ECMAScript version specified in your configuration (default ES5).
https://eslint.org/docs/latest/rules/func-name-matching
π Examples of correct code
var foo = function foo() {};
var foo = function() {};
var foo = () => {};
foo = function foo() {};
obj.foo = function foo() {};
obj['foo'] = function foo() {};
obj['foo//bar'] = function foo() {};
obj[foo] = function bar() {};
var obj = {foo: function foo() {}};
var obj = {[foo]: function bar() {}};
var obj = {'foo//bar': function foo() {}};
var obj = {foo: function() {}};
obj['x' + 2] = function bar(){};
var [ bar ] = [ function bar(){} ];
({[foo]: function bar() {}})
class C {
foo = function foo() {};
baz = function() {};
}
// private names are ignored
class D {
#foo = function foo() {};
#bar = function foo() {};
baz() {
this.#foo = function foo() {};
this.#foo = function bar() {};
}
}
module.exports = function foo(name) {};
module['exports'] = function foo(name) {};
π Examples of incorrect code
var foo = function bar() {};
foo = function bar() {};
obj.foo = function bar() {};
obj['foo'] = function bar() {};
var obj = {foo: function bar() {}};
({['foo']: function bar() {}});
class C {
foo = function bar() {};
}
"future reserved words" should not be used as identifiers Special identifiers should not be bound or assigned
https://sonarsource.github.io/rspec/#/rspec/S2137/javascript
π Examples of correct code
var elements = document.getElementsByName("foo"); // Compliant
var someData = { package: true };
result = 17;
++result;
var obj = { set p(arg) { } };
var result;
try { } catch (args) { }
function x(arg) { }
function args() { }
var y = function fun() { };
var f = new Function("args", "return 17;");
π Examples of incorrect code
var package = document.getElementsByName("foo"); // Noncompliant
eval = 17; // Noncompliant
arguments++; // Noncompliant
++eval; // Noncompliant
var obj = { set p(arguments) { } }; // Noncompliant
var eval; // Noncompliant
try { } catch (arguments) { } // Noncompliant
function x(eval) { } // Noncompliant
function arguments() { } // Noncompliant
var y = function eval() { }; // Noncompliant
var f = new Function("arguments", "return 17;"); // Noncompliant
Generators should "yield" something
https://sonarsource.github.io/rspec/#/rspec/S3531/javascript
π Examples of correct code
function* myGen(a, b) {
let answer = 0;
while (answer < 42) {
answer += a * b;
yield answer;
}
}
π Examples of incorrect code
function* myGen(a, b) { // Noncompliant
let answer = 0;
answer += a * b;
}
Assertion arguments should be passed in the correct order
https://sonarsource.github.io/rspec/#/rspec/S3415/javascript
π Examples of correct code
const assert = require('chai').assert;
const expect = require('chai').expect;
const should = require('chai').should();
it("inverts arguments", function() {
assert.equal(aNumber, 42);
expect(aNumber).to.equal(42);
should.fail(aNumber, 42);
});
π Examples of incorrect code
const assert = require('chai').assert;
const expect = require('chai').expect;
const should = require('chai').should();
it("inverts arguments", function() {
assert.equal(42, aNumber); // Noncompliant
expect(42).to.equal(aNumber); // Noncompliant
should.fail(42, aNumber); // Noncompliant
});
Union types should not have too many elements
https://sonarsource.github.io/rspec/#/rspec/S4622/javascript
π Examples of correct code
type MyUnionType = MyType1 | MyType2 | MyType3 | MyType4; // Compliant, "type" statements are ignored
let x: MyUnionType;
function foo(value: string, padding: MyUnionType) {
// ...
}
π Examples of incorrect code
let x: MyType1 | MyType2 | MyType3 | MyType4; // Noncompliant
function foo(p1: string, p2: MyType1 | MyType2 | MyType3 | MyType4) { // Noncompliant
// ...
}
Optional property declarations should not use both '?' and 'undefined' syntax
https://sonarsource.github.io/rspec/#/rspec/S4782/javascript
π Examples of correct code
interface Person {
name: string;
address: string | undefined;
pet?: Animal;
}
π Examples of incorrect code
interface Person {
name: string;
address? : string | undefined; // Noncompliant, "?" should be removed
pet?: Animal | undefined; // Noncompliant, "undefined" should be removed
}
Type guards should be used
https://sonarsource.github.io/rspec/#/rspec/S4322/javascript
π Examples of correct code
function isSomething(x: BaseType) : x is Something {
return (<Something>x).foo !== undefined;
}
if (isSomething(v)) {
v.foo();
}
π Examples of incorrect code
function isSomething(x: BaseType) : boolean { // Noncompliant
return (<Something>x).foo !== undefined;
}
if (isSomething(v)) {
(<Something>v).foo();
}
Delivering code in production with debug features activated is security-sensitive
https://sonarsource.github.io/rspec/#/rspec/S4507/javascript
π Examples of correct code
const express = require('express');
const errorhandler = require('errorhandler');
let app = express();
if (process.env.NODE_ENV === 'development') { // Compliant
app.use(errorhandler()); // Compliant
}
π Examples of incorrect code
const express = require('express');
const errorhandler = require('errorhandler');
let app = express();
app.use(errorhandler()); // Sensitive
Why use named groups only to never use any of them later on in the code?
This rule raises issues every time named groups are: defined but never called anywhere in the code through their name; defined but called elsewhere in the code by their number instead; referenced while not defined.
https://sonarsource.github.io/rspec/#/rspec/S5860/javascript
π Examples of correct code
const date = "01/02";
const datePattern = /(?<month>[0-9]{2})\/(?<year>[0-9]{2})/;
const dateMatched = date.match(datePattern);
if (dateMatched !== null) {
checkValidity(dateMatched.groups.month, dateMatched.groups.year);
}
// ...
const score = "14:1";
const scorePattern = /(?<player1>[0-9]+):(?<player2>[0-9]+)/;
const scoreMatched = score.match(scorePattern);
if (scoreMatched !== null) {
checkScore(scoreMatched.groups.player1);
checkScore(scoreMatched.groups.player2);
}
π Examples of incorrect code
const date = "01/02";
const datePattern = /(?<month>[0-9]{2})\/(?<year>[0-9]{2})/;
const dateMatched = date.match(datePattern);
if (dateMatched !== null) {
checkValidity(dateMatched[1], dateMatched[2]); // Noncompliant - numbers instead of names of groups are used
checkValidity(dateMatched.groups.day); // Noncompliant - there is no group called "day"
}
// ...
const score = "14:1";
const scorePattern = /(?<player1>[0-9]+):(?<player2>[0-9]+)/; // Noncompliant - named groups are never used
const scoreMatched = score.match(scorePattern);
if (scoreMatched !== null) {
checkScore(score);
}
A getter and setter for the same property donβt necessarily have to be defined adjacent to each other.
https://eslint.org/docs/latest/rules/grouped-accessor-pairs
π Examples of correct code
var foo = {
get a() {
return this.val;
},
set a(value) {
this.val = value;
},
b: 1
};
var bar = {
set b(value) {
this.val = value;
},
get b() {
return this.val;
},
a: 1
}
class Foo {
set a(value) {
this.val = value;
}
get a() {
return this.val;
}
b(){}
}
const Bar = class {
static get a() {
return this.val;
}
static set a(value) {
this.val = value;
}
}
π Examples of incorrect code
var foo = {
get a() {
return this.val;
},
b: 1,
set a(value) {
this.val = value;
}
};
var bar = {
set b(value) {
this.val = value;
},
a: 1,
get b() {
return this.val;
}
}
class Foo {
set a(value) {
this.val = value;
}
b(){}
get a() {
return this.val;
}
}
const Bar = class {
static get a() {
return this.val;
}
b(){}
static set a(value) {
this.val = value;
}
}
Enforce the consistent use of either function declarations or expressions
https://eslint.org/docs/latest/rules/func-style
π Examples of correct code
function foo() {
// ...
}
// Methods (functions assigned to objects) are not checked by this rule
SomeObject.foo = function() {
// ...
};
π Examples of incorrect code
var foo = function() {
// ...
};
var foo = () => {};
Disallow else blocks after return statements in if statements
https://eslint.org/docs/latest/rules/no-else-return
π Examples of correct code
function foo() {
if (x) {
return y;
}
return z;
}
function foo() {
if (x) {
return y;
} else if (z) {
var t = "foo";
} else {
return w;
}
}
function foo() {
if (x) {
if (z) {
return y;
}
} else {
return z;
}
}
function foo() {
if (error) {
return 'It failed';
} else if (loading) {
return "It's still loading";
}
}
π Examples of incorrect code
function foo() {
if (x) {
return y;
} else {
return z;
}
}
function foo() {
if (x) {
return y;
} else if (z) {
return w;
} else {
return t;
}
}
function foo() {
if (x) {
return y;
} else {
var t = "foo";
}
return t;
}
function foo() {
if (error) {
return 'It failed';
} else {
if (loading) {
return "It's still loading";
}
}
}
// Two warnings for nested occurrences
function foo() {
if (x) {
if (y) {
return y;
} else {
return x;
}
} else {
return z;
}
}
The console.log() method and similar methods joins the parameters with a space, so adding a leading/trailing space to a parameter, results in two spaces being added.
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-console-spaces.md
π Examples of correct code
console.log('abc');
console.log('abc', 'def');
console.log('abc ');
console.log(' abc');
console.log('abc ', 'def');
console.log('abc\t', 'def');
console.log('abc\n', 'def');
console.log(`
abc
`);
π Examples of incorrect code
console.log('abc ', 'def');
console.log('abc', ' def');
console.log("abc ", " def");
console.log(`abc `, ` def`);
console.debug('abc ', 'def');
console.info('abc ', 'def');
console.warn('abc ', 'def');
console.error('abc ', 'def');
Enforce the use of Unicode escapes instead of hexadecimal escapes
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-hex-escape.md
π Examples of correct code
const foo = '\u001B';
const foo = `\u001B${bar}`;
π Examples of incorrect code
const foo = '\x1B';
const foo = `\x1B${bar}`;
Prefer .flatMap(β¦) over .map(β¦).flat()
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-array-flat-map.md
π Examples of correct code
const foo = bar.flatMap(element => unicorn(element));
const foo = bar.map(element => unicorn(element)).flat(2);
const foo = bar.map(element => unicorn(element)).foo().flat();
const foo = bar.flat().map(element => unicorn(element));
π Examples of incorrect code
const foo = bar.map(element => unicorn(element)).flat();
const foo = bar.map(element => unicorn(element)).flat(1);
Prefer String#slice() over String#substr() and String#substring()
String#substr() and String#substring() are the two lesser known legacy ways to slice a string. It's better to use String#slice() as it's a more popular option with clearer behavior that has a consistent Array counterpart.
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-string-slice.md
π Examples of correct code
foo.slice(beginIndex, endIndex);
π Examples of incorrect code
foo.substr(start, length);
foo.substring(indexStart, indexEnd);
Prefer .before() over .insertBefore(), .replaceWith() over .replaceChild(), prefer one of .before(), .after(), .append() or .prepend() over insertAdjacentText() and insertAdjacentElement()
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-modern-dom-apis.md
π Examples of correct code
foo.replaceWith(bar);
foo.replaceWith('bar');
foo.replaceWith(bar, 'baz'));
foo.before(bar)
foo.before('bar')
foo.before(bar, 'baz')
foo.prepend(bar)
foo.prepend('bar')
foo.prepend(bar, 'baz')
foo.append(bar)
foo.append('bar')
foo.append(bar, 'baz')
foo.after(bar)
foo.after('bar')
foo.after(bar, 'baz')
π Examples of incorrect code
foo.replaceChild(baz, bar);
foo.insertBefore(baz, bar);
foo.insertAdjacentText('position', bar);
foo.insertAdjacentElement('position', bar);
Prefer Number static properties over global ones
π Examples of correct code
const foo = Number.parseInt('10', 2);
const foo = Number.parseFloat('10.5');
const foo = Number.isNaN(10);
const foo = Number.isFinite(10);
if (Object.is(foo, Number.NaN)) {}
const isPositiveZero = value => value === 0 && 1 / value === Number.POSITIVE_INFINITY;
const isNegativeZero = value => value === 0 && 1 / value === Number.NEGATIVE_INFINITY;
π Examples of incorrect code
const foo = parseInt('10', 2);
const foo = parseFloat('10.5');
const foo = isNaN(10);
const foo = isFinite(10);
if (Object.is(foo, NaN)) {}
const isPositiveZero = value => value === 0 && 1 / value === Infinity;
const isNegativeZero = value => value === 0 && 1 / value === -Infinity;
const {parseInt} = Number;
const foo = parseInt('10', 2);
Enforce the style of numeric separators by correctly grouping digits
π Examples of correct code
const foo = 1_234_444;
const foo = 1_234.567_89;
const foo = 0xAB_CD_EF;
const foo = 0b1000_1111;
const foo = 0o10_4421;
const foo = 1_294_287_712n;
π Examples of incorrect code
const foo = 1_23_4444;
const foo = 1_234.56789;
const foo = 0xAB_C_D_EF;
const foo = 0b10_00_1111;
const foo = 0o1_0_44_21;
const foo = 1_294_28771_2n;
Prefer default parameters over reassignment
π Examples of correct code
function abc(foo = 'bar') {}
function abc(foo) {
const parameter = foo || bar();
}
π Examples of incorrect code
function abc(foo) {
foo = foo || 'bar';
}
function abc(foo) {
const bar = foo || 'bar';
}
Prefer Array#flat() over legacy techniques to flatten arrays
https://github.com/freaktechnik/eslint-plugin-array-func#avoid-reverse
π Examples of correct code
const string = array.reduceRight((p, c) => p + c, "");
const reverseString = array.reduce((p, c) => p + c, "");
π Examples of incorrect code
const string = array.reverse().reduce((p, c) => p + c, '');
const reverseString = array.reverse().reduceRight((p, c) => p + c, '');
Optional boolean parameters should have default value
https://sonarsource.github.io/rspec/#/rspec/S4798/javascript
π Examples of correct code
function countPositiveNumbers(arr: number[], countZero = false) {
// ...
}
function toggleProperty(property: string, value: boolean) {
setProperty(property, value);
}
function togglePropertyToCalculatedValue(property: string) {
setProperty(property, calculateProperty());
}
π Examples of incorrect code
// Noncompliant, default value for 'countZero' should be defined
function countPositiveNumbers(arr: number[], countZero?: boolean) {
// ...
}
function toggleProperty(property: string, value?: boolean) { // Noncompliant, a new function should be defined
if (value !== undefined) {
setProperty(property, value);
} else {
setProperty(property, calculateProperty());
}
}
Class names should comply with a naming convention
https://sonarsource.github.io/rspec/#/rspec/S101/javascript
π Examples of correct code
// With default provided regular expression /^[A-Z][a-zA-Z0-9]*$/:
class MyClass { }
π Examples of incorrect code
class my_class { }
Class methods should be used instead of "prototype" assignments
https://sonarsource.github.io/rspec/#/rspec/S3525/javascript
π Examples of correct code
class MyClass {
constructor(initializerArgs = []) {
this._values = [...initializerArgs];
}
doSomething() {
//...
}
}
π Examples of incorrect code
function MyNonClass(initializerArgs = []) {
this._values = [...initializerArgs];
}
MyNonClass.prototype.doSomething = function () { // Noncompliant
// ...
}
Comma and logical OR operators should not be used in switch cases
https://sonarsource.github.io/rspec/#/rspec/S3616/javascript
π Examples of correct code
switch (a) {
case 1:
case 2:
doTheThing(a);
case 3:
case 4:
doThatThing(a);
case 5:
doTheOtherThing(a);
default:
console.log('Neener, neener!');
}
π Examples of incorrect code
switch (a) {
case 1,2: // Noncompliant; only 2 is ever handled by this case
doTheThing(a);
case 3 || 4: // Noncompliant; only '3' is handled
doThatThing(a);
case 5:
doTheOtherThing(a);
default:
console.log('Neener, neener!'); // this happens when a==1 or a == 4
}
Prefer class properties to equivalent setup steps taken in a class' constructor method.
https://github.com/markalfred/eslint-plugin-no-constructor-bind
π Examples of correct code
class User {
greet = () => 'hello'
}
π Examples of incorrect code
class User {
constructor() {
this.greet = this.greet.bind(this)
}
greet() { return 'Hello' }
}
Prefer String#codePointAt(β¦) over String#charCodeAt(β¦) and String.fromCodePoint(β¦) over String.fromCharCode(β¦)
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-code-point.md
π Examples of correct code
const unicorn = 'π¦'.codePointAt(0).toString(16);
const unicorn = String.fromCodePoint(0x1f984);
π Examples of incorrect code
const unicorn = 'π¦'.charCodeAt(0).toString(16);
const unicorn = String.fromCharCode(0x1f984);
If an object is defined as "thenable", once it's accidentally used in an await expression, it may cause problems:
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-thenable.md
π Examples of correct code
export {then as success};
const foo = {
success() {}
};
class Foo {
success() {}
}
const foo = bar.then;
π Examples of incorrect code
export {then};
const foo = {
then() {}
};
const foo = {
get then() {}
};
foo.then = function () {}
class Foo {
then() {}
}
class Foo {
static then() {}
}
IIFE with parenthesized arrow function body is considered unreadable.
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-unreadable-iife.md
π Examples of correct code
const bar = getBar();
const foo = bar ? bar.baz : baz;
const getBaz = bar => (bar ? bar.baz : baz);
const foo = getBaz(getBar());
const foo = (bar => {
return bar ? bar.baz : baz;
})(getBar());
π Examples of incorrect code
const foo = (bar => (bar ? bar.baz : baz))(getBar());
const foo = ((bar, baz) => ({bar, baz}))(bar, baz);
Prefer using String, Number, BigInt, Boolean, and Symbol directly
π Examples of correct code
const toBoolean = Boolean;
if (Number(foo) === 1) {}
const hasTruthyValue = array.some(Boolean);
const toStringObject = value => new String(value);
const toObject = value => Object(value);
π Examples of incorrect code
const toBoolean = value => Boolean(value);
function toNumber(value) {
return Number(value);
}
if (toNumber(foo) === 1) {}
const hasTruthyValue = array.some(element => element);
Prefer using a logical operator over a ternary
Ideally, most reported cases have an equivalent Logical OR(||) expression. The rule intentionally provides suggestions instead of auto-fixes, because in many cases, the nullish coalescing operator (??) should be preferred.
π Examples of correct code
foo ?? bar;
foo || bar;
foo ? bar : baz;
foo.bar ?? foo.baz
foo?.bar ?? baz
π Examples of incorrect code
foo ? foo : bar;
foo.bar ? foo.bar : foo.baz
foo?.bar ? foo.bar : baz
!bar ? foo : bar;
Prefer EventTarget over EventEmitter
While EventEmitter is only available in Node.js, EventTarget is also available in Deno and browsers.
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-event-target.md
π Examples of correct code
class Foo extends EventTarget {}
const target = new EventTarget();
π Examples of incorrect code
import {EventEmitter} from 'node:event';
class Foo extends EventEmitter {}
const emitter = new EventEmitter();
Prefer using Object.fromEntries(β¦) to transform a list of key-value pairs into an object
π Examples of correct code
const object = Object.fromEntries(pairs);
const object = new Map(pairs);
π Examples of incorrect code
const object = pairs.reduce(
(object, [key, value]) => ({...object, [key]: value}),
{}
);
const object = pairs.reduce(
(object, [key, value]) => ({...object, [key]: value}),
Object.create(null)
);
const object = pairs.reduce(
(object, [key, value]) => Object.assign(object, {[key]: value}),
{}
);
const object = _.fromPairs(pairs);
Prefer using the mapFn callback of Array.from over an immediate .map() call on the Array.from result.
https://github.com/freaktechnik/eslint-plugin-array-func#from-map
π Examples of correct code
Array.from(iterable).map((t) => t.id);
Array.from(iterable, (t) => t.id).map((id) => id[0]);
π Examples of incorrect code
Array.from(iterable, (t) => t.id);
Array.from(iterable, function(t) { this.format(t); }, this);
const arr = Array.from(iterable);
const mappedArray = arr.map((t) => t.id);
Use .flat() to flatten an array of arrays. This rule currently recognizes two patterns and can replace them with a .flat() call:
https://github.com/freaktechnik/eslint-plugin-array-func#prefer-flat https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-array-flat.md
π Examples of correct code
const concatFlat = array.flat();
const reverseFlat = array.reduce((p, n) => n.concat(p), []);
const otherReduce = array.reduce((p, n) => n + p, 0);
π Examples of incorrect code
const concatFlat = [].concat(...array);
const reduceFlat = array.reduce((p, n) => p.concat(n), []);
https://eslint.org/docs/rules/consistent-this#consistent-this
π Examples of correct code
var bar = function() {};
const cat = {
meow: function() {}
}
class C {
#bar = function() {};
baz = function() {};
}
quux ??= function() {};
(function bar() {
// ...
}())
export default function foo() {}
π Examples of incorrect code
var that = 42;
var self = this;
that = 42;
self = this;
this.a = 0;
baz(() => this);
(function() {
this.a = 0;
baz(() => this);
})();
function foo() {
this.a = 0;
baz(() => this);
}
var foo = function() {
this.a = 0;
baz(() => this);
};
Enforces use dot notation
https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/dot-notation.md https://eslint.org/docs/rules/dot-notation
π Examples of correct code
var x = foo.bar;
var x = foo[bar];
π Examples of incorrect code
var x = foo["bar"];
Enforces that this
is used when only this
type is returned.
π Examples of correct code
class Foo {
f1(): this {
return this;
}
f2() {
return this;
}
f3 = (): this => {
return this;
};
f4 = () => {
return this;
};
}
class Base {}
class Derived extends Base {
f(): Base {
return this;
}
}
π Examples of incorrect code
class Foo {
f1(): Foo {
return this;
}
f2 = (): Foo => {
return this;
};
f3(): Foo | undefined {
return Math.random() > 0.5 ? this : undefined;
}
}
Require calls to isNaN() when checking for NaN
https://eslint.org/docs/latest/rules/use-isnan
π Examples of correct code
if (isNaN(foo)) {
// ...
}
if (!isNaN(foo)) {
// ...
}
π Examples of incorrect code
if (foo == NaN) {
// ...
}
if (foo != NaN) {
// ...
}
if (foo == Number.NaN) {
// ...
}
if (foo != Number.NaN) {
// ...
}
https://eslint.org/docs/rules/dot-location#dot-location https://eslint.org/docs/rules/no-whitespace-before-property
π Examples of correct code
foo.bar
foo[bar]
foo[ bar ]
foo.bar.baz
foo
.bar().baz()
foo
.bar()
.baz()
π Examples of incorrect code
foo [bar]
foo. bar
foo .bar
foo. bar. baz
foo. bar()
.baz()
foo
.bar(). baz()
Not allow trailing whitespace
https://eslint.org/docs/rules/dot-location#dot-location https://eslint.org/docs/rules/no-whitespace-before-property
π Examples of correct code
var foo = 0;
var baz = 5;
class A {
b = 1;
}
π Examples of incorrect code
var foo = 0;//β’β’β’β’β’
var baz = 5;//β’β’
class A {
//β’β’
b = 1;
//β’β’
}
//β’β’
Require consistent spacing around type annotations.
https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/type-annotation-spacing.md https://eslint.style/rules/ts/type-annotation-spacing
π Examples of correct code
let foo: string = "bar";
function foo(): string {}
class Foo {
name: string;
}
type Foo = () => {};
π Examples of incorrect code
let foo:string = "bar";
let foo :string = "bar";
let foo : string = "bar";
function foo():string {}
function foo() :string {}
function foo() : string {}
class Foo {
name:string;
}
class Foo {
name :string;
}
class Foo {
name : string;
}
type Foo = ()=>{};
type Foo = () =>{};
type Foo = ()=> {};
This rule enforces a maximum number of statements allowed per line.
https://eslint.org/docs/rules/max-statements-per-line
π Examples of correct code
var bar, baz;
if (condition) bar = 1;
for (var i = 0; i < length; ++i);
switch (discriminant) { default: }
function foo() { }
var foo = function foo() { };
(function foo() { })();
π Examples of incorrect code
var bar; var baz;
if (condition) { bar = 1; }
for (var i = 0; i < length; ++i) { bar = 1; }
switch (discriminant) { default: break; }
function foo() { bar = 1; }
var foo = function foo() { bar = 1; };
(function foo() { bar = 1; })();
Disallows constant expressions in conditions. always use variables instead.
https://eslint.org/docs/rules/no-constant-condition#no-constant-condition
π Examples of correct code
if (x === 0) {
doSomething();
}
for (let i = 0; i < 2; i++) {
}
while (typeof x === "undefined") {
doSomething();
}
do {
doSomething();
} while (x);
var result = x !== 0 ? a : b;
π Examples of incorrect code
if (false) {
doSomethingUnfinished();
}
if (void x) {
doSomethingUnfinished();
}
if (x &&= false) {
doSomethingNever();
}
if (class {}) {
doSomethingAlways();
}
if (new Boolean(x)) {
doSomethingAlways();
}
if (Boolean(1)) {
doSomethingAlways();
}
if (undefined) {
doSomethingUnfinished();
}
if (x ||= true) {
doSomethingAlways();
}
for (;-2;) {
doSomethingForever();
}
while (typeof x) {
doSomethingForever();
}
do {
doSomethingForever();
} while (x = -1);
var result = 0 ? a : b;
Debugger not recommended use break point.
https://eslint.org/docs/rules/no-debugger#no-debugger
π Examples of correct code
function isTruthy(x) {
return Boolean(x); // set a breakpoint at this line
}
π Examples of incorrect code
function isTruthy(x) {
debugger;
return Boolean(x);
}
No Duplicate case in switch
https://eslint.org/docs/rules/no-duplicate-case#no-duplicate-case
π Examples of correct code
switch (a) {
case 1:
break;
case 2:
break;
case 3:
break;
default:
break;
}
switch (a) {
case one:
break;
case two:
break;
case three:
break;
default:
break;
}
switch (a) {
case "1":
break;
case "2":
break;
case "3":
break;
default:
break;
π Examples of incorrect code
switch (a) {
case 1:
break;
case 2:
break;
case 1: // duplicate test expression
break;
default:
break;
}
switch (a) {
case one:
break;
case 2:
break;
case one: // duplicate test expression
break;
default:
break;
}
switch (a) {
case "1":
break;
case "2":
break;
case "1": // duplicate test expression
break;
default:
break;
}
https://eslint.org/docs/rules/no-empty-character-class#no-empty-character-class
π Examples of correct code
/^abc/.test("abcdefg"); // true
"abcdefg".match(/^abc/); // ["abc"]
/^abc[a-z]/.test("abcdefg"); // true
"abcdefg".match(/^abc[a-z]/); // ["abcd"]
// valid regex
RegExp('.')
new RegExp
this.RegExp('[')
π Examples of incorrect code
/^abc[]/.test("abcdefg"); // false
"abcdefg".match(/^abc[]/); // null
// invalid regex
RegExp('[')
RegExp('.', 'z')
new RegExp('\\')
Disallows empty character classes in regular expressions.
https://eslint.org/docs/rules/no-ex-assign#no-ex-assign
π Examples of correct code
try {
// code
} catch (e) {
var foo = 10;
}
π Examples of incorrect code
try {
// code
} catch (e) {
e = 10;
}
Disallows unnecessary semicolons.
https://eslint.org/docs/rules/no-extra-semi#no-extra-semi
π Examples of correct code
var x = 5;
function foo() {
// code
}
var bar = function() {
// code
};
class C {
field;
method() {
// code
}
static {
// code
}
}
π Examples of incorrect code
var x = 5;;
function foo() {
// code
};
class C {
field;;
method() {
// code
};
static {
// code
};
};
Disallows reassigning function declarations.
https://eslint.org/docs/rules/no-func-assign#no-func-assign
π Examples of correct code
var foo = function () {}
foo = bar;
function foo(foo) { // `foo` is shadowed.
}
π Examples of incorrect code
function foo() {}
foo = bar;
function foo() {
foo = bar;
}
var a = function hello() {
hello = 123;
};
Disallow deleting variables.
https://eslint.org/docs/latest/rules/no-delete-var
π Examples of correct code
// don't remove
π Examples of incorrect code
var x;
delete x;
Disallow unnecessary nested blocks
https://eslint.org/docs/latest/rules/no-lone-blocks
π Examples of correct code
while (foo) {
bar();
}
if (foo) {
if (bar) {
baz();
}
}
function bar() {
baz();
}
{
let x = 1;
}
{
const y = 1;
}
{
class Foo {}
}
aLabel: {
}
class C {
static {
lbl: {
if (something) {
break lbl;
}
foo();
}
}
}
π Examples of incorrect code
if (foo) {
bar();
{
baz();
}
}
function bar() {
{
baz();
}
}
{
function foo() {}
}
{
aLabel: {
}
}
class C {
static {
{
foo();
}
}
}
Disallow the use of the proto property
https://eslint.org/docs/latest/rules/no-proto
π Examples of correct code
var a = Object.getPrototypeOf(obj);
Object.setPrototypeOf(obj, b);
var c = { __proto__: a };
π Examples of incorrect code
var a = obj.__proto__;
var a = obj["__proto__"];
obj.__proto__ = b;
obj["__proto__"] = b;
Disallows variable or function declarations in nested blocks.
https://eslint.org/docs/rules/no-func-assign#no-func-assign
π Examples of correct code
function doSomething() { }
function doSomethingElse() {
function doAnotherThing() { }
}
class C {
static {
function doSomething() { }
}
}
if (test) {
asyncCall(id, function (err, data) { });
}
var fn;
if (test) {
fn = function fnExpression() { };
}
if (foo) var a;
π Examples of incorrect code
if (test) {
function doSomething() { }
}
function doSomethingElse() {
if (test) {
function doAnotherThing() { }
}
}
if (foo) function f(){}
class C {
static {
if (test) {
function doSomething() { }
}
}
}
Disallow \8 and \9 escape sequences in string literals
https://eslint.org/docs/latest/rules/no-nonoctal-decimal-escape
π Examples of correct code
"8";
"9";
var foo = "w8less";
var bar = "December 19";
var baz = "Don't use \\8 and \\9 escapes.";
var quux = "\0\u0038";
π Examples of incorrect code
"\8";
"\9";
var foo = "w\8less";
var bar = "December 1\9";
var baz = "Don't use \8 and \9 escapes.";
var quux = "\0\8";
Node.js allows the import of modules using an absolute path such as /home/xyz/file.js. That is a bad practice as it ties the code using it to your computer, and therefore makes it unusable in packages distributed on npm for instance.
https://github.com/import-js/eslint-plugin-import/blob/HEAD/docs/rules/no-absolute-path.md
π Examples of correct code
import _ from 'lodash';
import foo from 'foo';
import foo from './foo';
var _ = require('lodash');
var foo = require('foo');
var foo = require('./foo');
π Examples of incorrect code
import f from '/foo';
import f from '/some/path';
var f = require('/foo');
var f = require('/some/path');
Forbid Webpack loader syntax in imports.
https://github.com/import-js/eslint-plugin-import/blob/HEAD/docs/rules/no-webpack-loader-syntax.md
π Examples of correct code
import myModule from 'my-module';
import theme from './theme.css';
var myModule = require('my-module');
var theme = require('./theme.css');
π Examples of incorrect code
import myModule from 'my-loader!my-module';
import theme from 'style!css!./theme.css';
var myModule = require('my-loader!./my-module');
var theme = require('style!css!./theme.css');
Disallow magic numbers
https://eslint.org/docs/latest/rules/no-magic-numbers
π Examples of correct code
var TAX = 0.25;
var dutyFreePrice = 100,
finalPrice = dutyFreePrice + (dutyFreePrice * TAX);
π Examples of incorrect code
var dutyFreePrice = 100,
finalPrice = dutyFreePrice + (dutyFreePrice * 0.25);
// or
var data = ['foo', 'bar', 'baz'];
var dataLast = data[2];
Disallows variable or function declarations in nested blocks.
https://eslint.org/docs/rules/no-negated-in-lhs#no-negated-in-lhs
π Examples of correct code
if(!(key in object)) {
// key is not in object
}
π Examples of incorrect code
if(!key in object) {
// operator precedence makes it equivalent to (!key) in object
// and type conversion makes it equivalent to (key ? "false" : "true") in object
}
Disallows multiple spaces in regular expression literals.
https://eslint.org/docs/rules/no-regex-spaces#no-regex-spaces
π Examples of correct code
var re = /foo {3}bar/;
var re = new RegExp("foo {3}bar");
// better
var re = /foo {3}bar/;
var re = new RegExp("foo\s{3}bar");
π Examples of incorrect code
var re = /foo bar/;
var re = new RegExp("foo bar");
Disallows sparse arrays.
https://eslint.org/docs/rules/no-sparse-arrays#no-sparse-arrays
π Examples of correct code
var items = [];
var items = new Array(23);
// trailing comma (after the last element) is not a problem
var colors = [ "red", "blue", ];
π Examples of incorrect code
var items = [,];
var colors = [ "red",, "blue" ];
Enforces comparing typeof expressions against valid strings.
https://eslint.org/docs/rules/valid-typeof#valid-typeof
π Examples of correct code
typeof foo === "string"
typeof bar == "undefined"
typeof foo === baz
typeof bar === typeof qux
π Examples of incorrect code
typeof foo === "strnig"
typeof foo == "undefimed"
typeof bar != "nunber"
typeof bar !== "fucntion"
Requires the use of === and !== instead of == and !=. It is considered good practice to use the type-safe equality operators === and !== instead of their regular counterparts == and !=.
https://eslint.org/docs/rules/eqeqeq#eqeqeq
π Examples of correct code
a === b
foo === true
bananas !== 1
value === undefined
typeof foo === 'undefined'
'hello' !== 'world'
0 === 0
true === true
foo === null
π Examples of incorrect code
a == b
foo == true
bananas != 1
value == undefined
typeof foo == 'undefined'
'hello' != 'world'
0 == 0
true == true
foo == null
https://eslint.org/docs/rules/no-extra-label#no-extra-label https://eslint.org/docs/rules/no-labels#no-labels
π Examples of correct code
while (a) {
break;
}
for (let i = 0; i < 10; ++i) {
break;
}
switch (a) {
case 0:
break;
}
π Examples of incorrect code
A: while (a) {
break A;
}
B: for (let i = 0; i < 10; ++i) {
break B;
}
C: switch (a) {
case 0:
break C;
}
Disallows leading or trailing decimal points in numeric literals.
https://eslint.org/docs/rules/no-floating-decimal#no-floating-decimal
π Examples of correct code
var num = 0.5;
var num = 2.0;
var num = -0.7;
π Examples of incorrect code
var num = .5;
var num = 2.;
var num = -.7;
Disallows reassignment of native objects.
https://eslint.org/docs/rules/no-floating-decimal#no-floating-decimal
π Examples of correct code
a = 1
var b = 1
b = 2
onload = function() {}
/*global a:writable*/
a = 1
π Examples of incorrect code
Object = null;
undefined = 1;
window = {};
length = 1;
top = 1;
/*global a:readonly*/
a = 1
Disallows new
operators outside of assignments or comparisons.
https://eslint.org/docs/rules/no-new#no-new
π Examples of correct code
var thing = new Thing();
Thing();
π Examples of incorrect code
new Thing();
Disallows new operators with the Function object. It's possible to create functions in JavaScript from strings at runtime using the Function constructor, such as:
https://eslint.org/docs/rules/no-new-func#no-new-func
π Examples of correct code
var x = function (a, b) {
return a + b;
};
π Examples of incorrect code
var x = new Function("a", "b", "return a + b");
var x = Function("a", "b", "return a + b");
var x = Function.call(null, "a", "b", "return a + b");
var x = Function.apply(null, ["a", "b", "return a + b"]);
var x = Function.bind(null, "a", "b", "return a + b")();
// assuming that the result of Function.bind(...) will be eventually called.
var f = Function.bind(null, "a", "b", "return a + b");
Disallows variable redeclarations.
https://eslint.org/docs/rules/no-redeclare#no-redeclare https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/no-redeclare.md
π Examples of correct code
var a = 3;
a = 10;
class C {
foo() {
var b = 3;
b = 10;
}
static {
var c = 3;
c = 10;
}
}
π Examples of incorrect code
var a = 3;
var a = 10;
class C {
foo() {
var b = 3;
var b = 10;
}
static {
var c = 3;
var c = 10;
}
}
Disallows comparisons where both sides are exactly the same.
https://eslint.org/docs/rules/no-self-compare#no-self-compare
π Examples of correct code
var x = 10;
var y = 10;
if (x === y) {
x = 20;
}
π Examples of incorrect code
var x = 10;
if (x === x) {
x = 20;
}
Disallows unmodified conditions of loops.
https://eslint.org/docs/rules/no-unmodified-loop-condition#no-unmodified-loop-condition
π Examples of correct code
while (node) {
doSomething(node);
node = node.parent;
}
for (var j = 0; j < items.length; ++j) {
doSomething(items[j]);
}
// OK, the result of this binary expression is changed in this loop.
while (node !== root) {
doSomething(node);
node = node.parent;
}
// OK, the result of this ternary expression is changed in this loop.
while (node ? A : B) {
doSomething(node);
node = node.parent;
}
// A property might be a getter which has side effect...
// Or "doSomething" can modify "obj.foo".
while (obj.foo) {
doSomething(obj);
}
// A function call can return various values.
while (check(obj)) {
doSomething(obj);
}
π Examples of incorrect code
var node = something;
while (node) {
doSomething(node);
}
node = other;
for (var j = 0; j < items.length; ++i) {
doSomething(items[j]);
}
while (node !== root) {
doSomething(node);
}
Disallows unnecessary escape characters.
https://eslint.org/docs/rules/no-useless-escape#no-useless-escape
π Examples of correct code
"\"";
'\'';
"\x12";
"\u00a9";
"\371";
"xs\u2111";
`\``;
`\${${foo}}`;
`$\{${foo}}`;
/\\/g;
/\t/g;
/\w\$\*\^\./;
/[[]/;
/[\]]/;
/[a-z-]/;
π Examples of incorrect code
"\'";
'\"';
"\#";
"\e";
`\"`;
`\"${foo}\"`;
`\#{foo}`;
/\!/;
/\@/;
/[\[]/;
/[a-z\-]/;
Disallows "Yoda" conditions.
https://eslint.org/docs/rules/yoda#yoda
Yoda conditions are so named because the literal value of the condition comes first while the variable comes second. For example, the following is a Yoda condition:
π Examples of correct code
if (5 & value) {
// ...
}
if (value === "red") {
// ...
}
if (value === `red`) {
// ...
}
if (`${value}` === `red`) {
}
π Examples of incorrect code
if ("red" === color) {
// ...
}
if (`red` === color) {
// ...
}
if (`red` === `${color}`) {
// ...
}
if (true == flag) {
// ...
}
if (5 > count) {
// ...
}
if (-1 < str.indexOf(substr)) {
// ...
}
if (0 <= x && x < 1) {
// ...
}
Disallows initializing variables to undefined.
https://eslint.org/docs/rules/no-undef-init#no-undef-init
π Examples of correct code
var foo;
let bar;
const foo = undefined;
let { bar = undefined } = baz;
[quux = undefined] = quuux;
(foo = undefined) => {};
class Foo {
bar = undefined;
}
π Examples of incorrect code
var foo = undefined;
let bar = undefined;
Disallows new operators with calls to require.
https://eslint.org/docs/rules/no-new-require#no-new-require
π Examples of correct code
var AppHeader = require('app-header');
var appHeader = new AppHeader();
π Examples of incorrect code
var appHeader = new require('app-header');
Disallow Object constructors
https://eslint.org/docs/rules/no-new-object
π Examples of correct code
var myObject = new CustomObject();
var myObject = {};
var Object = function Object() {};
new Object();
π Examples of incorrect code
var myObject = new Object();
new Object();
Disallow new operators with the Symbol object
https://eslint.org/docs/latest/rules/no-new-symbol
π Examples of correct code
var foo = Symbol('foo');
// Ignores shadowed Symbol.
function bar(Symbol) {
const baz = new Symbol("baz");
}
π Examples of incorrect code
var foo = new Symbol('foo');
Enforce minimum identifier lengths
https://eslint.org/docs/latest/rules/id-length
π Examples of correct code
var num = 5;
function _f() { return 42; }
function _func() { return 42; }
obj.el = document.body;
var foo = function (evt) { /* do stuff */ };
try {
dangerousStuff();
} catch (error) {
// ignore as many do
}
var myObj = { apple: 1 };
(num) => { num * num };
function foo(num = 0) { }
class MyClass { }
class Foo { method() {} }
class Foo { #method() {} }
class Foo { field = 1 }
class Foo { #field = 1 }
function foo(...args) { }
function foo([longName]) { }
var { prop } = {};
var { prop: [longName] } = {};
var [longName] = arr;
function foo({ prop }) { }
function foo({ a: prop }) { }
var { prop } = {};
var { a: prop } = {};
({ prop: obj.longName } = {});
var data = { "x": 1 }; // excused because of quotes
data["y"] = 3; // excused because of calculated property access
π Examples of incorrect code
var x = 5;
obj.e = document.body;
var foo = function (e) { };
try {
dangerousStuff();
} catch (e) {
// ignore as many do
}
var myObj = { a: 1 };
(a) => { a * a };
class x { }
class Foo { x() {} }
class Foo { #x() {} }
class Foo { x = 1 }
class Foo { #x = 1 }
function foo(...x) { }
function foo([x]) { }
var [x] = arr;
var { prop: [x]} = {};
function foo({x}) { }
var { x } = {};
var { prop: a} = {};
({ prop: obj.x } = {});
Enforce a maximum depth that blocks can be nested
https://eslint.org/docs/latest/rules/max-depth
π Examples of correct code
function foo() {
for (;;) { // Nested 1 deep
while (true) { // Nested 2 deep
if (true) { // Nested 3 deep
}
}
}
}
π Examples of incorrect code
function foo() {
for (;;) { // Nested 1 deep
while (true) { // Nested 2 deep
if (true) { // Nested 3 deep
if (true) { // Nested 4 deep
if (true) { // Nested 5 deep
}
}
}
}
}
}
Enforce a maximum number of parameters in function definitions
https://eslint.org/docs/latest/rules/max-params https://www.npmjs.com/package/eslint-plugin-better-max-params
π Examples of correct code
function foo (bar, baz, qux) {
doSomething();
}
let foo = (bar, baz, qux) => {
doSomething();
};
π Examples of incorrect code
function foo (bar, baz, qux, qxx) {
doSomething();
}
let foo = (bar, baz, qux, qxx) => {
doSomething();
};
Enforce a maximum number of parameters in function definitions
https://eslint.org/docs/latest/rules/max-statements
π Examples of correct code
function foo() {
var foo1 = 1;
var foo2 = 2;
var foo3 = 3;
var foo4 = 4;
var foo5 = 5;
var foo6 = 6;
var foo7 = 7;
var foo8 = 8;
var foo9 = 9;
var foo10 = 10;
return function () {
// The number of statements in the inner function does not count toward the
// statement maximum.
return 42;
};
}
let foo = () => {
var foo1 = 1;
var foo2 = 2;
var foo3 = 3;
var foo4 = 4;
var foo5 = 5;
var foo6 = 6;
var foo7 = 7;
var foo8 = 8;
var foo9 = 9;
var foo10 = 10;
return function () {
// The number of statements in the inner function does not count toward the
// statement maximum.
return 42;
};
}
π Examples of incorrect code
function foo() {
var foo1 = 1;
var foo2 = 2;
var foo3 = 3;
var foo4 = 4;
var foo5 = 5;
var foo6 = 6;
var foo7 = 7;
var foo8 = 8;
var foo9 = 9;
var foo10 = 10;
var foo11 = 11; // Too many.
}
let foo = () => {
var foo1 = 1;
var foo2 = 2;
var foo3 = 3;
var foo4 = 4;
var foo5 = 5;
var foo6 = 6;
var foo7 = 7;
var foo8 = 8;
var foo9 = 9;
var foo10 = 10;
var foo11 = 11; // Too many.
};
Require or disallow assignment operator shorthand where possible
https://eslint.org/docs/latest/rules/operator-assignment
π Examples of correct code
x = y;
x += y;
x = y * z;
x = (x * y) * z;
x[0] /= y;
x[foo()] = x[foo()] % 2;
x = y + x; // `+` is not always commutative (e.g. x = "abc")
π Examples of incorrect code
x = x + y;
x = y * x;
x[0] = x[0] / y;
x.y = x.y << z;
Require generator functions to contain yield
https://eslint.org/docs/latest/rules/require-yield
π Examples of correct code
function* foo() {
yield 5;
return 10;
}
function foo() {
return 10;
}
// This rule does not warn on empty generator functions.
function* foo() { }
π Examples of incorrect code
function* foo() {
return 10;
}
Require rest parameters instead of arguments
https://eslint.org/docs/latest/rules/prefer-rest-params
π Examples of correct code
function foo(...args) {
console.log(args);
}
function foo(action, ...args) {
action.apply(null, args); // or `action(...args)`, related to the `prefer-spread` rule.
}
// Note: the implicit arguments can be overwritten.
function foo(arguments) {
console.log(arguments); // This is the first argument.
}
function foo() {
var arguments = 0;
console.log(arguments); // This is a local variable.
}
π Examples of incorrect code
function foo() {
console.log(arguments);
}
function foo(action) {
var args = Array.prototype.slice.call(arguments, 1);
action.apply(null, args);
}
function foo(action) {
var args = [].slice.call(arguments, 1);
action.apply(null, args);
}
Require symbol descriptions
https://eslint.org/docs/latest/rules/symbol-description
π Examples of correct code
var foo = Symbol("some description");
// or
var someString = "some description";
var bar = Symbol(someString);
π Examples of incorrect code
var foo = Symbol();
Disallow unnecessary return await
https://eslint.org/docs/latest/rules/no-return-await
π Examples of correct code
async function foo() {
return bar();
}
async function foo() {
await bar();
return;
}
// This is essentially the same as `return await bar();`, but the rule checks only `await` in `return` statements
async function foo() {
const x = await bar();
return x;
}
// In this example the `await` is necessary to be able to catch errors thrown from `bar()`
async function foo() {
try {
return await bar();
} catch (error) {}
}
π Examples of incorrect code
async function foo() {
return await bar();
}
Enforce a maximum 1 classes per file
https://eslint.org/docs/latest/rules/max-classes-per-file
π Examples of correct code
class Foo {}
π Examples of incorrect code
class Foo {}
class Bar {}
Disallow returning value from constructor
https://eslint.org/docs/latest/rules/no-constructor-return
π Examples of correct code
class C {
constructor(c) {
this.c = c;
}
}
class D {
constructor(f) {
if (!f) {
return; // Flow control.
}
f();
}
}
π Examples of incorrect code
class A {
constructor(a) {
this.a = a;
return a;
}
}
class B {
constructor(f) {
if (!f) {
return 'falsy';
}
}
}
Prefira o operador de exponencial
https://eslint.org/docs/latest/rules/prefer-exponentiation-operator
π Examples of correct code
const foo = 2 ** 8;
const bar = a ** b;
let baz = (a + b) ** (c + d);
let quux = (-1) ** n;
π Examples of incorrect code
const foo = Math.pow(2, 8);
const bar = Math.pow(a, b);
let baz = Math.pow(a + b, c + d);
let quux = Math.pow(-1, n);
Disallow using Object.assign with an object literal as the first argument and prefer the use of object spread instead.
https://eslint.org/docs/latest/rules/prefer-object-spread
π Examples of correct code
({ ...foo });
({ ...baz, foo: 'bar' });
// Any Object.assign call without an object literal as the first argument
Object.assign(foo, { bar: baz });
Object.assign(foo, bar);
Object.assign(foo, { bar, baz });
Object.assign(foo, { ...baz });
π Examples of incorrect code
Object.assign({}, foo);
Object.assign({}, {foo: 'bar'});
Object.assign({ foo: 'bar'}, baz);
Object.assign({}, baz, { foo: 'bar' });
Object.assign({}, { ...baz });
// Object.assign with a single argument that is an object literal
Object.assign({});
Object.assign({ foo: bar });
Enforce getter and setter pairs in objects and classes
https://eslint.org/docs/latest/rules/accessor-pairs
π Examples of correct code
var o = {
set a(value) {
this.val = value;
},
get a() {
return this.val;
}
};
var myObject = { d: 1 };
Object.defineProperty(myObject, 'c', {
set: function(value) {
this.val = value;
},
get: function() {
return this.val;
}
});
π Examples of incorrect code
var o = {
set a(value) {
this.val = value;
}
};
var myObject = { d: 1 };
Object.defineProperty(myObject, 'c', {
set: function(value) {
this.val = value;
}
});
Enforce default clauses in switch statements to be last
https://eslint.org/docs/latest/rules/default-case-last
π Examples of correct code
π Examples of incorrect code
switch (foo) {
default:
bar();
break;
case "a":
baz();
break;
}
switch (foo) {
case 1:
bar();
break;
default:
baz();
break;
case 2:
quux();
break;
}
switch (foo) {
case "x":
bar();
break;
default:
case "y":
baz();
break;
}
switch (foo) {
default:
break;
case -1:
bar();
break;
}
switch (foo) {
default:
doSomethingIfNotZero();
case 0:
doSomethingAnyway();
}
Suggests using template literals instead of string concatenation.
https://eslint.org/docs/rules/prefer-template#prefer-template
π Examples of correct code
var str = "Hello World!";
var str = `Hello, ${name}!`;
var str = `Time: ${12 * 60 * 60 * 1000}`;
// This is reported by `no-useless-concat`.
var str = "Hello, " +
"World!";
π Examples of incorrect code
var str = "Hello, " + name + "!";
var str = "Time: " + (12 * 60 * 60 * 1000);
Prevents conditionals where the type is always truthy or always falsy.
π Examples of correct code
function head<T>(items: T[]) {
// Necessary, since items.length might be 0
if (items.length) {
return items[0].toUpperCase();
}
}
function foo(arg: string) {
// Necessary, since foo might be ''.
if (arg) {
}
}
function bar(arg?: string | null) {
// Necessary, since arg might be nullish
return arg?.length;
}
[0, 1, 2, 3].filter(t => t); // number can be truthy or falsy
π Examples of incorrect code
function head<T>(items: T[]) {
// items can never be nullable, so this is unnecessary
if (items) {
return items[0].toUpperCase();
}
}
function foo(arg: 'bar' | 'baz') {
// arg is never nullable or empty string, so this is unnecessary
if (arg) {
}
}
function bar<T>(arg: string) {
// arg can never be nullish, so ?. is unnecessary
return arg?.length;
}
// Checks array predicate return types, where possible
[
[1, 2],
[3, 4],
].filter(t => t); // number[] is always truthy
we should avoid using lots of white spaces, this takes up the screen and tries to supply a bad organization with spaces
https://eslint.org/docs/rules/no-multiple-empty-lines
π Examples of correct code
function foo<T>(items: T[]) {
}
function bar(arg: string) {
}
π Examples of incorrect code
function foo<T>(items: T[]) {
// \r\n
// \r\n
}
// \n
// \n
function bar(arg: string) {
// \n
// \n
}
Block misused new instance
π Examples of correct code
class C {
constructor() {}
}
interface I {
new (): C;
}
π Examples of incorrect code
class C {
new(): C;
}
interface I {
new (): I;
constructor(): void;
}
Disallows space before semicolon.
https://eslint.org/docs/rules/semi-spacing
π Examples of correct code
var foo;
var foo; var bar;
throw new Error("error");
while (a) { break; }
for (i = 0; i < 10; i++) {}
π Examples of incorrect code
var foo ;
var foo;var bar;
throw new Error("error") ;
while (a) { break ; }
for (i = 0 ; i < 10 ; i++) {}
for (i = 0;i < 10;i++) {}
Disallow specific types from being used. Disallow any use.
https://typescript-eslint.io/rules/ban-types https://typescript-eslint.io/rules/no-explicit-any
π Examples of correct code
// use lower-case primitives for consistency
const str: string = 'foo';
const bool: boolean = true;
const num: number = 1;
const symb: symbol = Symbol('foo');
// use a proper function type
const func: () => number = () => 1;
// use safer object types
const lowerObj: object = {};
const capitalObj1: number = 1;
const capitalObj2: { a: string } = { a: 'string' };
const curly1: number = 1;
const curly2: Record<'a', string> = { a: 'string' };
interface ObjInterface {
a: number
}
const obj: ObjInterface = { a: 1 };
π Examples of incorrect code
// use lower-case primitives for consistency
const str: String = 'foo';
const bool: Boolean = true;
const num: Number = 1;
const symb: Symbol = Symbol('foo');
// use a proper function type
const func: Function = () => 1;
// use safer object types
const capitalObj1: Object = 1;
const capitalObj2: Object = { a: 'string' };
const curly1: {} = 1;
const curly2: {} = { a: 'string' };
const obj: any = { a: 1 };
Disallow empty functions
https://typescript-eslint.io/rules/no-empty-function
π Examples of correct code
function foo() {
// do nothing.
}
var foo = function() {
// any clear comments.
};
var foo = () => {
bar();
};
function* foo() {
// do nothing.
}
var foo = function*() {
// do nothing.
};
var obj = {
foo: function() {
// do nothing.
},
foo: function*() {
// do nothing.
},
foo() {
// do nothing.
},
*foo() {
// do nothing.
},
get foo() {
// do nothing.
},
set foo(value) {
// do nothing.
}
};
class A {
constructor() {
// do nothing.
}
foo() {
// do nothing.
}
*foo() {
// do nothing.
}
get foo() {
// do nothing.
}
set foo(value) {
// do nothing.
}
static foo() {
// do nothing.
}
static *foo() {
// do nothing.
}
static get foo() {
// do nothing.
}
static set foo(value) {
// do nothing.
}
}
π Examples of incorrect code
function foo() {}
var foo = function() {};
var foo = () => {};
function* foo() {}
var foo = function*() {};
var obj = {
foo: function() {},
foo: function*() {},
foo() {},
*foo() {},
get foo() {},
set foo(value) {}
};
class A {
constructor() {}
foo() {}
*foo() {}
get foo() {}
set foo(value) {}
static foo() {}
static *foo() {}
static get foo() {}
static set foo(value) {}
}
Disallow duplicate imports.
https://typescript-eslint.io/rules/no-duplicate-imports https://github.com/import-js/eslint-plugin-import/blob/HEAD/docs/rules/no-duplicates.md
π Examples of correct code
import { merge, find } from "module";
import something from "another-module";
// or
import * as something from "another-module";
π Examples of incorrect code
import { merge } from "module";
import something from "another-module";
import { find } from "module";
Disallows unnecessary constraints on generic types.
https://typescript-eslint.io/rules/no-unnecessary-type-constraint
π Examples of correct code
interface Foo<T> {}
type Bar<T> = {};
class Baz<T> {
qux<U> { }
}
const Quux = <T>() => {};
function Quuz<T>() {}
π Examples of incorrect code
interface FooAny<T extends any> {}
interface FooUnknown<T extends unknown> {}
type BarAny<T extends any> = {};
type BarUnknown<T extends unknown> = {};
class BazAny<T extends any> {
quxUnknown<U extends unknown>() {}
}
class BazUnknown<T extends unknown> {
quxUnknown<U extends unknown>() {}
}
const QuuxAny = <T extends any>() => {};
const QuuxUnknown = <T extends unknown>() => {};
function QuuzAny<T extends any>() {}
function QuuzUnknown<T extends unknown>() {}
The use of arguments.caller
and arguments.callee
make several code optimizations impossible.
They have been deprecated in future versions of JavaScript and their use
is forbidden in ECMAScript 5 while in strict mode.
https://eslint.org/docs/rules/no-caller
π Examples of correct code
function foo(n) {
if (n <= 0) {
return;
}
foo(n - 1);
}
[1,2,3,4,5].map(function factorial(n) {
return !(n > 1) ? 1 : factorial(n - 1) * n;
});
π Examples of incorrect code
function foo(n) {
if (n <= 0) {
return;
}
arguments.callee(n - 1);
}
[1,2,3,4,5].map(function(n) {
return !(n > 1) ? 1 : arguments.callee(n - 1) * n;
});
This rule disallows dangling underscores in identifiers.
https://eslint.org/docs/rules/no-underscore-dangle
π Examples of correct code
var _ = require('underscore');
var obj = _.contains(items, item);
obj.__proto__ = {};
var file = __filename;
function foo(_bar) {};
const foo = { onClick(_bar) {} };
const foo = (_bar) => {};
π Examples of incorrect code
var foo_;
var __proto__ = {};
foo._bar();
function _foo(_bar) {};
This rule aims to prevent unintended behavior caused by modification or reassignment of function parameters.
https://eslint.org/docs/rules/no-param-reassign
π Examples of correct code
function foo(bar) {
var baz = bar;
}
π Examples of incorrect code
function foo(bar) {
bar = 13;
}
function foo(bar) {
bar++;
}
function foo(bar) {
for (bar in baz) {}
}
function foo(bar) {
for (bar of baz) {}
}
If a variable is never reassigned, using the const declaration is better.
https://eslint.org/docs/rules/prefer-const https://typescript-eslint.io/rules/prefer-as-const
π Examples of correct code
const a = 0;
// it's never initialized.
let a;
console.log(a);
// it's reassigned after initialized.
let a;
a = 0;
a = 1;
console.log(a);
// it's initialized in a different block from the declaration.
let a;
if (true) {
a = 0;
}
console.log(a);
// it's initialized in a different scope.
let a;
class C {
#x;
static {
a = obj => obj.#x;
}
}
// it's initialized at a place that we cannot write a variable declaration.
let a;
if (true) a = 0;
console.log(a);
// `i` gets a new binding each iteration
for (const i in [1, 2, 3]) {
console.log(i);
}
// `a` gets a new binding each iteration
for (const a of [1, 2, 3]) {
console.log(a);
}
let foo = 'bar';
let foo = 'bar' as const;
let foo: 'bar' = 'bar' as const;
let bar = 'bar' as string;
let foo = <string>'bar';
let foo = { bar: 'baz' };
π Examples of incorrect code
let a = 3;
console.log(a);
let a;
a = 0;
console.log(a);
class C {
static {
let a;
a = 0;
console.log(a);
}
}
// `i` is redefined (not reassigned) on each loop step.
for (let i in [1, 2, 3]) {
console.log(i);
}
// `a` is redefined (not reassigned) on each loop step.
for (let a of [1, 2, 3]) {
console.log(a);
}
let bar: 2 = 2;
let foo = <'bar'>'bar';
let foo = { bar: 'baz' as 'baz' };
Requires using either T[] instead of Array<T>.
https://typescript-eslint.io/rules/array-type
π Examples of correct code
const x: string[] = ['a', 'b'];
const y: readonly string[] = ['a', 'b'];
const a: Array<string | number> = ['a', 'b'];
π Examples of incorrect code
const x: Array<string> = ['a', 'b'];
const y: ReadonlyArray<string> = ['a', 'b'];
Disallows awaiting a value that is not a Thenable.
https://typescript-eslint.io/rules/await-thenable
π Examples of correct code
await Promise.resolve('value');
const createValue = async () => 'value';
await createValue();
π Examples of incorrect code
await 'value';
const createValue = () => 'value';
await createValue();
Enforces using a particular method signature syntax.
https://typescript-eslint.io/rules/method-signature-style
π Examples of correct code
interface T1 {
func(arg: string): number;
}
type T2 = {
func(arg: boolean): void;
};
interface T3 {
func(arg: number): void;
func(arg: string): void;
func(arg: boolean): void;
}
π Examples of incorrect code
interface T1 {
func: (arg: string) => number;
}
type T2 = {
func: (arg: boolean) => void;
};
// this is equivalent to the overload
interface T3 {
func: ((arg: number) => void) &
((arg: string) => void) &
((arg: boolean) => void);
}
Warns if a type assertion does not change the type of an expression.
https://typescript-eslint.io/rules/no-unnecessary-type-assertion
π Examples of correct code
const foo = <number>3;
const foo = 3 as number;
const foo: number = 3;
const foo = 'foo' as const;
π Examples of incorrect code
const foo = 3;
const bar = foo!;
const foo = <3>3;
type Foo = 3;
const foo = <Foo>3;
type Foo = 3;
const foo = 3 as Foo;
This rule disallows calling any variable that is typed as any.
https://typescript-eslint.io/rules/no-unsafe-call
π Examples of correct code
declare const typedVar: () => void;
declare const typedNested: { prop: { a: () => void } };
typedVar();
typedNested.prop.a();
(() => {})();
new Map();
String.raw`foo`;
π Examples of incorrect code
declare const anyVar: any;
declare const nestedAny: { prop: any };
anyVar();
anyVar.a.b();
nestedAny.prop();
nestedAny.prop['a']();
new anyVar();
new nestedAny.prop();
anyVar`foo`;
nestedAny.prop`foo`;
Requires let or const instead of var.
https://eslint.org/docs/rules/no-var
π Examples of correct code
let x = "y";
const CONFIG = {};
// init var is better
let y;
if (CONFIG.y) {
y = CONFIG.y;
}
console.log(y);
π Examples of incorrect code
var x = "y";
var CONFIG = {};
if (CONFIG.y) {
var y = CONFIG.y;
}
console.log(y);
The operator-linebreak rule is aimed at enforcing a particular operator line break style
https://eslint.org/docs/rules/operator-linebreak
π Examples of correct code
foo = 1 + 2;
foo = 1
+ 2
+ 3;
foo = 5;
if (
someCondition
|| otherCondition
) {
// code ...
}
answer = everything
? 42
: foo;
class Foo {
a = 1;
[b] = 2;
d = 4;
}
π Examples of incorrect code
foo = 1 +
2;
foo =
5;
foo
= 5;
if (
someCondition ||
otherCondition
) {
}
answer = everything ?
42 :
foo;
class Foo {
a =
1;
[b] =
2;
[c
] =
3;
}
Enforces spacing before * in generator functions.
https://eslint.org/docs/rules/generator-star-spacing
π Examples of correct code
function *generator() {}
var anonymous = function *() {};
var shorthand = { *generator() {} };
π Examples of incorrect code
function* generator() {}
var anonymous = function* () {};
var shorthand = { * generator() {} };
Enforces spacing before * in generator functions.
https://eslint.org/docs/rules/no-unsafe-optional-chaining
π Examples of correct code
(obj?.foo)?.();
obj?.foo();
(obj?.foo ?? bar)();
obj?.foo.bar;
obj.foo?.bar;
foo?.()?.bar;
(obj?.foo ?? bar)`template`;
new (obj?.foo ?? bar)();
var baz = {...obj?.foo};
const { bar } = obj?.foo || baz;
async function foo () {
const { bar } = await obj?.foo || baz;
(await obj?.foo)?.();
(await obj?.foo)?.bar;
}
π Examples of incorrect code
(obj?.foo)();
(obj?.foo).bar;
(foo?.()).bar;
(foo?.()).bar();
(obj?.foo ?? obj?.bar)();
(foo || obj?.foo)();
(obj?.foo && foo)();
(foo ? obj?.foo : bar)();
(foo, obj?.bar).baz;
(obj?.foo)`template`;
new (obj?.foo)();
[...obj?.foo];
bar(...obj?.foo);
1 in obj?.foo;
bar instanceof obj?.foo;
for (bar of obj?.foo);
const { bar } = obj?.foo;
[{ bar } = obj?.foo] = [];
with (obj?.foo);
class A extends obj?.foo {}
var a = class A extends obj?.foo {};
async function foo () {
const { bar } = await obj?.foo;
(await obj?.foo)();
(await obj?.foo).bar;
}
Array has several methods for filtering, mapping, and folding. If we forget to write return statement in a callback of those, it's probably a mistake.
https://eslint.org/docs/rules/array-callback-return https://sonarsource.github.io/rspec/#/rspec/S3796/javascript
π Examples of correct code
var indexMap = myArray.reduce(function(memo, item, index) {
memo[item] = index;
return memo;
}, {});
var foo = Array.from(nodes, function(node) {
if (node.tagName === "DIV") {
return true;
}
return false;
});
var bar = foo.map(node => node.getAttribute("id"));
π Examples of incorrect code
var indexMap = myArray.reduce(function(memo, item, index) {
memo[item] = index;
}, {});
var foo = Array.from(nodes, function(node) {
if (node.tagName === "DIV") {
return true;
}
});
var bar = foo.filter(function(x) {
if (x) {
return true;
} else {
return;
}
});
Requires spacing around infix operators.
https://eslint.org/docs/rules/space-infix-ops https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/space-infix-ops.md https://eslint.style/rules/ts/space-infix-ops https://eslint.org/docs/rules/key-spacing https://eslint.style/rules/ts/key-spacing
π Examples of correct code
a + b
a ? b : c
const a = {b:1};
var {a = 0} = bar;
function foo(a = 0) { }
function foo(a = 0): string | number { }
var obj = { "foo": 42 };
π Examples of incorrect code
a+b
a+ b
a +b
a?b:c
const a={b:1};
var {a=0}=bar;
function foo(a=0) { }
function foo(): string|number { }
var obj = { "foo" : 42 };
var obj = { "foo" :42 };
Requires following curly brace conventions.
https://eslint.org/docs/rules/curly
π Examples of correct code
if (foo) {
bar();
baz();
} else {
buz();
}
if (foo) {
bar();
} else if (faa) {
bor();
} else {
other();
things();
}
if (true)
foo();
else
baz();
if (foo)
foo++;
π Examples of incorrect code
if (foo) {
bar();
baz();
} else
buz();
if (foo)
bar();
else if (faa)
bor();
else {
other();
things();
}
if (true)
foo();
else {
baz();
}
if (foo) {
foo++;
}
Requires quotes around all object literal property names if any name strictly requires quotes, otherwise disallows quotes around object property names.
https://eslint.org/docs/rules/quote-props
π Examples of correct code
var object1 = {
"foo": "bar",
"baz": 42,
"qux-lorem": true
};
var object2 = {
foo: 'bar',
baz: 42
};
π Examples of incorrect code
var object1 = {
foo: "bar",
"baz": 42,
"qux-lorem": true
};
var object2 = {
'foo': 'bar',
'baz': 42
};
Enforces consistent brace style for blocks.
https://eslint.org/docs/rules/brace-style
π Examples of correct code
function foo() {
return true;
}
if (foo) {
bar();
}
if (foo) {
bar();
} else {
baz();
}
try {
somethingRisky();
} catch(e) {
handleError();
}
class C {
static {
foo();
}
}
// when there are no braces, there are no problems
if (foo) bar();
else if (baz) boom();
π Examples of incorrect code
function foo()
{
return true;
}
if (foo)
{
bar();
}
try
{
somethingRisky();
} catch(e)
{
handleError();
}
if (foo) {
bar();
}
else {
baz();
}
class C
{
static
{
foo();
}
}
This rule enforce consistent comma style in array literals, object literals, and variable declarations.
https://eslint.org/docs/rules/comma-style
π Examples of correct code
var foo = 1, bar = 2;
var foo = 1,
bar = 2;
var foo = ["apples",
"oranges"];
function bar() {
return {
"a": 1,
"b:": 2
};
}
π Examples of incorrect code
var foo = 1,
bar = 2;
var foo = ["apples",
"oranges"];
function bar() {
return {
"a": 1,
"b:": 2
};
}
Enforces placing object properties on separate lines.
https://eslint.org/docs/rules/object-property-newline
π Examples of correct code
const obj1 = { foo: "foo", bar: "bar", baz: "baz" };
const obj2 = {
foo: "foo",
bar: "bar",
baz: "baz",
};
const user = process.argv[2];
const obj3 = {
user,
[ process.argv[3] ? "foo" : "bar" ]: 0,
baz: [
1,
2,
4,
8,
]
};
π Examples of incorrect code
const obj1 = {
foo: "foo", bar: "bar", baz: "baz"
};
const obj2 = {
foo: "foo", bar: "bar",
baz: "baz"
};
const obj3 = {
[process.argv[3] ? "foo" : "bar"]: 0, baz: [
1,
2,
4,
8
]
};
A number of style guides require or disallow line breaks inside of object braces and other tokens.
https://eslint.org/docs/latest/rules/object-curly-newline
π Examples of correct code
let a = {};
let b = { foo: 1 };
let c = { foo: 1, bar: 2 };
let d = {
foo: 1,
bar: 2,
};
let e = {
foo: function() {
dosomething();
}
};
let { f } = obj;
let { g, h } = obj;
let {
i,
j
} = obj;
let { k = () => dosomething() } = obj;
π Examples of incorrect code
let b = {
foo: 1
};
let c = { foo: 1,
bar: 2 };
let d = {foo: 1
, bar: 2};
let e = { foo: function() {
dosomething();
} };
let {i,
j} = obj;
Negated conditions are more difficult to understand. Code can be made more readable by inverting the condition instead.
https://eslint.org/docs/latest/rules/no-negated-condition
π Examples of correct code
if (!a) {
doSomething();
}
if (!a) {
doSomething();
} else if (b) {
doSomething();
}
if (a != b) {
doSomething();
}
a ? b : c
π Examples of incorrect code
if (!a) {
doSomething();
} else {
doSomethingElse();
}
if (a != b) {
doSomething();
} else {
doSomethingElse();
}
if (a !== b) {
doSomething();
} else {
doSomethingElse();
}
!a ? c : b
Having two cases in a switch statement or two branches in an if chain with the same implementation is at best duplicate code, and at worst a coding error. If the same logic is truly needed for both instances, then in an if chain they should be combined, or for a switch, one should fall through to the other.
https://github.com/SonarSource/eslint-plugin-sonarjs/blob/HEAD/docs/rules/no-duplicated-branches.md
π Examples of correct code
switch (i) {
case 1:
case 3:
doFirstThing();
doSomething();
break;
case 2:
doSomethingDifferent();
break;
default:
doTheRest();
}
if ((a >= 0 && a < 10) || (a >= 20 && a < 50)) {
doFirstThing();
doTheThing();
} else if (a >= 10 && a < 20) {
doTheOtherThing();
} else {
doTheRest();
}
// Or
switch (i) {
case 1:
doFirstThing();
doSomething();
break;
case 2:
doSomethingDifferent();
break;
case 3:
doFirstThing();
doThirdThing();
break;
default:
doTheRest();
}
if (a >= 0 && a < 10) {
doFirstThing();
doTheThing();
} else if (a >= 10 && a < 20) {
doTheOtherThing();
} else if (a >= 20 && a < 50) {
doFirstThing();
doTheThirdThing();
} else {
doTheRest();
}
π Examples of incorrect code
switch (i) {
case 1:
doFirstThing();
doSomething();
break;
case 2:
doSomethingDifferent();
break;
case 3: // Noncompliant; duplicates case 1's implementation
doFirstThing();
doSomething();
break;
default:
doTheRest();
}
if (a >= 0 && a < 10) {
doFirstThing();
doTheThing();
} else if (a >= 10 && a < 20) {
doTheOtherThing();
} else if (a >= 20 && a < 50) {
// Noncompliant; duplicates first condition
doFirstThing();
doTheThing();
} else {
doTheRest();
}
When two functions have the same implementation, either it was a mistake - something else was intended - or the duplication was intentional, but may be confusing to maintainers. In the latter case, the code should be refactored.
https://github.com/SonarSource/eslint-plugin-sonarjs/blob/HEAD/docs/rules/no-identical-functions.md
π Examples of correct code
function calculateCode() {
doTheThing();
doOtherThing();
return code;
}
function getName() {
return calculateCode();
}
π Examples of incorrect code
function calculateCode() {
doTheThing();
doOtherThing();
return code;
}
function getName() { // Noncompliant
doTheThing();
doOtherThing();
return code;
}
It is needlessly complex to invert the result of a boolean comparison. The opposite comparison should be made instead.
π Examples of correct code
if (a !== 2) { ... }
π Examples of incorrect code
if (!(a === 2)) { ... } // Noncompliant
Nested switch structures are difficult to understand because you can easily confuse the cases of an inner switch as belonging to an outer statement. Therefore nested switch statements should be avoided.
https://github.com/SonarSource/eslint-plugin-sonarjs/blob/HEAD/docs/rules/no-nested-switch.md
π Examples of correct code
function foo(n, m) {
switch (n) {
case 0:
return bar(m);
case 1:
// ...
default:
// ...
}
}
function bar(m) {
switch(m) {
// ...
}
}
π Examples of incorrect code
function foo(n, m) {
switch (n) {
case 0:
switch (m) { // Noncompliant; nested switch
// ...
}
case 1:
// ...
default:
// ...
}
}
Template literals (previously named "template strings") are an elegant way to build a string without using the + operator to make strings concatenation more readable.
π Examples of correct code
let color = "red";
let count = 3;
let apples = color ? `${count} ${color}` : count;
let message = `I have ${apples} apples`;
π Examples of incorrect code
let color = "red";
let count = 3;
let message = `I have ${color ? `${count} ${color}` : count} apples`;
Redundant Boolean literals should be removed from expressions to improve readability.
https://github.com/SonarSource/eslint-plugin-sonarjs/blob/HEAD/docs/rules/no-redundant-boolean.md
π Examples of correct code
if (booleanMethod()) { /* ... */ }
if (!booleanMethod()) { /* ... */ }
if (booleanMethod()) { /* ... */ }
doSomething(true);
doSomething(booleanMethod());
π Examples of incorrect code
if (booleanMethod() == true) { /* ... */ }
if (booleanMethod() == false) { /* ... */ }
if (booleanMethod() || false) { /* ... */ }
doSomething(!false);
doSomething(booleanMethod() == true);
Declaring a variable only to immediately return or throw it is a bad practice.
https://github.com/SonarSource/eslint-plugin-sonarjs/blob/HEAD/docs/rules/prefer-immediate-return.md
π Examples of correct code
function ms(hours, minutes, seconds) {
return ((hours * 60 + minutes) * 60 + seconds) * 1000;
}
π Examples of incorrect code
function ms(hours, minutes, seconds) {
const duration = ((hours * 60 + minutes) * 60 + seconds) * 1000;
return duration;
}
Object literal syntax, which initializes an object's properties inside the object declaration is cleaner and clearer than the alternative: creating an empty object, and then giving it properties one by one.
https://github.com/SonarSource/eslint-plugin-sonarjs/blob/HEAD/docs/rules/prefer-object-literal.md
π Examples of correct code
var person = {
firstName: "John",
middleInitial: "Q",
lastName: "Public",
};
π Examples of incorrect code
var person = {}; // Noncompliant
person.firstName = "John";
person.middleInitial = "Q";
person.lastName = "Public";
Return of boolean literal statements wrapped into if-then-else flow should be simplified.
π Examples of correct code
return expression;
π Examples of incorrect code
if (expression) {
return true;
} else {
return false;
}
// or
if (expression) {
return true;
}
return false;
Enforces placing object properties on separate lines.
Then any code used within the same scope would not get the global undefined, but rather the local version with a very different meaning.
https://eslint.org/docs/rules/no-shadow https://eslint.org/docs/rules/no-shadow-restricted-names https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/no-shadow.md https://sonarsource.github.io/rspec/#/rspec/S1527/javascript
π Examples of correct code
var a = 3;
function b() {
var c = 10;
}
var b = function () {
var c = 10;
}
function b(a) {
var c = 10;
}
b(a);
function f(a, b){}
var elements = document.getElementsByName("foo"); // Compliant
var someData = { package: true }; // Compliant, as it is not used as an identifier here
π Examples of incorrect code
var a = 3;
function b() {
var a = 10;
}
var b = function () {
var a = 10;
}
function b(a) {
a = 10;
}
b(a);
if (true) {
let a = 5;
}
function NaN(){}
!function(Infinity){};
var undefined = 5;
try {} catch(eval){}
var package = document.getElementsByName("foo"); // Noncompliant
This rule enforces consistent line breaks inside parentheses of function parameters or arguments.
https://eslint.org/docs/latest/rules/function-paren-newline https://eslint.org/docs/latest/rules/function-call-argument-newline
π Examples of correct code
function foo(
bar,
baz
) {}
var foo = function(bar, baz) {};
var foo = (
bar
) => {};
foo(
function() {
return baz;
}
);
foo("one", "two", "three");
// or
foo(
"one",
"two",
"three"
);
bar("one", "two", {
one: 1,
two: 2
});
// or
bar(
"one",
"two",
{ one: 1, two: 2 }
);
// or
bar(
"one",
"two",
{
one: 1,
two: 2
}
);
baz("one", "two", (x) => {
console.log(x);
});
// or
baz(
"one",
"two",
(x) => {
console.log(x);
}
);
π Examples of incorrect code
function foo(bar,
baz
) {}
var foo = function(bar,
baz) {};
var foo = (
bar) => {};
foo(
function() {
return baz;
});
foo("one", "two",
"three");
//or
foo("one",
"two", "three");
bar("one", "two",
{ one: 1, two: 2}
);
baz("one", "two",
(x) => { console.log(x); }
);
Disallows space between the function name and the opening parenthesis.
https://eslint.org/docs/latest/rules/func-call-spacing https://eslint.style/rules/ts/function-call-spacing
π Examples of correct code
fn();
π Examples of incorrect code
fn ();
fn
();
This rule enforces line breaks between array elements.
https://eslint.org/docs/latest/rules/array-element-newline
π Examples of correct code
var a = [];
var b = [1];
var c = [1, 2];
var d = [1, 2, 3];
var e = [
1,
2
];
var f = [
1,
2,
3
];
var g = [
function foo() {
dosomething();
}, function bar() {
dosomething();
}, function baz() {
dosomething();
}
];
var h = [
function foo() {
dosomething();
},
function bar() {
dosomething();
},
function baz() {
dosomething();
}
];
π Examples of incorrect code
var a = [
1, 2,
3
];
var b = [
function foo() {
dosomething();
}, function bar() {
dosomething();
},
function baz() {
dosomething();
}
];
Enforces always wrapping the function expression
https://eslint.org/docs/latest/rules/wrap-iife
π Examples of correct code
var x = (function () { return { y: 1 }; })(); // wrapped function expression
π Examples of incorrect code
var x = function () { return { y: 1 };}(); // unwrapped
var x = (function () { return { y: 1 };}()); // wrapped call expression
Disallows spaces between a tag function and its template literal.
https://eslint.org/docs/latest/rules/template-tag-spacing
π Examples of correct code
func`Hello world`;
π Examples of incorrect code
func `Hello world`;
Enforce spacing between rest and spread operators and their expressions
https://eslint.org/docs/latest/rules/rest-spread-spacing
π Examples of correct code
fn(...args)
[...arr, 4, 5, 6]
let [a, b, ...arr] = [1, 2, 3, 4, 5];
function fn(...args) { console.log(args); }
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
let n = { x, y, ...z };
π Examples of incorrect code
fn(... args)
[... arr, 4, 5, 6]
let [a, b, ... arr] = [1, 2, 3, 4, 5];
function fn(... args) { console.log(args); }
let { x, y, ... z } = { x: 1, y: 2, a: 3, b: 4 };
let n = { x, y, ... z };
Disallows a newline before a single-line statement.
https://eslint.org/docs/latest/rules/nonblock-statement-body-position
π Examples of correct code
if (foo) bar();
else baz();
while (foo) bar();
for (let i = 1; i < foo; i++) bar();
do bar(); while (foo)
if (foo) { // block statements are always allowed with this rule
bar();
} else {
baz();
}
π Examples of incorrect code
if (foo)
bar();
else
baz();
while (foo)
bar();
for (let i = 1; i < foo; i++)
bar();
do
bar();
while (foo)
This rule can enforce or disallow parentheses when invoking a constructor with no arguments using the new keyword.
https://eslint.org/docs/latest/rules/new-parens
π Examples of correct code
var person = new Person();
var person = new Person("name");
π Examples of incorrect code
var person = new Person;
var person = new (Person);
The shorthand can be used if the assignment target and the left expression of a logical expression are the same.
For example a = a || b
can be shortened to a ||= b
.
https://eslint.org/docs/latest/rules/logical-assignment-operators
π Examples of correct code
a = b
a += b
a ||= b
a = b || c
a || (b = c)
if (a) a = b
π Examples of incorrect code
a = a || b
a = a && b
a = a ?? b
a || (a = b)
a && (a = b)
a ?? (a = b)
The with statement is potentially problematic because it adds members of an object to the current scope, making it impossible to tell what a variable inside the block actually refers to.
https://eslint.org/docs/rules/no-with
π Examples of correct code
const r = ({x, y}) => Math.sqrt(x * x + y * y);
π Examples of incorrect code
with (point) {
r = Math.sqrt(x * x + y * y); // is r a member of point?
}
Calling a Promise static method with new is invalid, resulting in a TypeError at runtime.
https://github.com/xjamundx/eslint-plugin-promise/blob/development/docs/rules/no-new-statics.md
π Examples of correct code
Promise.resolve(value)
Promise.reject(error)
Promise.race([p1, p2])
Promise.all([p1, p2])
π Examples of incorrect code
new Promise.resolve(value)
new Promise.reject(error)
new Promise.race([p1, p2])
new Promise.all([p1, p2])
Ensure that inside a then() or a catch() we always return or throw a raw value instead of wrapping in Promise.resolve or Promise.reject
https://github.com/xjamundx/eslint-plugin-promise/blob/development/docs/rules/no-new-statics.md
π Examples of correct code
myPromise.then(function (val) {
return val * 2
})
myPromise.then(function (val) {
throw new Exception("Message");
})
π Examples of incorrect code
myPromise.then(function (val) {
return Promise.resolve(val * 2)
})
myPromise.then(function (val) {
return Promise.reject('bad thing')
})
Ensure that inside a then() or a catch() we always return or throw a raw value instead of wrapping in Promise.resolve or Promise.reject
https://github.com/xjamundx/eslint-plugin-promise/blob/development/docs/rules/param-names.md
π Examples of correct code
new Promise(function (resolve) { ... })
new Promise(function (resolve, reject) { ... })
new Promise(function (_resolve, _reject) { ... }) // Unused marker for parameters are allowed
π Examples of incorrect code
new Promise(function (reject, resolve) { ... }) // incorrect order
new Promise(function (ok, fail) { ... }) // non-standard parameter names
new Promise(function (_, reject) { ... }) // a simple underscore is not allowed
Ensure that inside a then() or a catch() we always return or throw a raw value instead of wrapping in Promise.resolve or Promise.reject
https://github.com/xjamundx/eslint-plugin-promise/blob/development/docs/rules/always-return.md
π Examples of correct code
myPromise.then((val) => val * 2);
myPromise.then(function(val) { return val * 2; });
myPromise.then(doSomething); // could be either
myPromise.then((b) => { if (b) { return "yes" } else { return "no" } });
π Examples of incorrect code
myPromise.then(function (val) {})
myPromise.then(() => {
doSomething()
})
myPromise.then((b) => {
if (b) {
return 'yes'
} else {
forgotToReturn()
}
})
Warning
Avoid nested then() or catch() statements (no-nesting)
https://github.com/xjamundx/eslint-plugin-promise/blob/development/docs/rules/no-nesting.md
π Examples of correct code
myPromise.then(doSomething).then(doSomethingElse).catch(errors)
π Examples of incorrect code
myPromise.then((val) => doSomething(val).then(doSomethingElse))
myPromise.then((val) => doSomething(val).catch(errors))
myPromise.catch((err) => doSomething(err).then(doSomethingElse))
myPromise.catch((err) => doSomething(err).catch(errors))
Disallow return statements inside a callback passed to finally(), since nothing would consume what's returned.
π Examples of correct code
myPromise.finally(function (val) {
console.log('value:', val)
})
π Examples of incorrect code
myPromise.finally(function (val) {
return val
})
Disallow return statements inside a callback passed to finally(), since nothing would consume what's returned.
https://github.com/xjamundx/eslint-plugin-promise/blob/development/docs/rules/valid-params.md
π Examples of correct code
// Promise.all() requires 1 argument
Promise.all([p1, p2, p3])
Promise.all(iterable)
// Promise.race() requires 1 argument
Promise.race([p1, p2, p3])
Promise.race(iterable)
// Promise.resolve() requires 0 or 1 arguments
Promise.resolve()
Promise.resolve({})
Promise.resolve([1, 2, 3])
Promise.resolve(referenceToObject)
// Promise.reject() requires 0 or 1 arguments
Promise.reject()
Promise.reject(Error())
Promise.reject(referenceToError)
// Promise.then() requires 1 or 2 arguments
somePromise().then((value) => doSomething(value))
somePromise().then(successCallback, errorCallback)
// Promise.catch() requires 1 argument
somePromise().catch((error) => {
handleError(error)
})
somePromise().catch(console.error)
// Promise.finally() requires 1 argument
somePromise().finally(() => {
console.log('done!')
})
somePromise().finally(console.log)
π Examples of incorrect code
Promise.all() // is called with 0 or 2+ arguments
Promise.race() // is called with 0 or 2+ arguments
Promise.resolve(a, b) // is called with 2+ arguments
Promise.reject(a, b) // is called with 2+ arguments
Promise.then() // is called with 0 or 3+ arguments
Promise.catch() // is called with 0 or 2+ arguments
Promise.finally() // is called with 0 or 2+ arguments
Disallows using an async function as a Promise executor.
https://eslint.org/docs/rules/no-async-promise-executor
π Examples of correct code
const foo = new Promise((resolve, reject) => {
readFile('foo.txt', function(err, result) {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});
const result = Promise.resolve(foo);
π Examples of incorrect code
const foo = new Promise(async (resolve, reject) => {
readFile('foo.txt', function(err, result) {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});
const result = new Promise(async (resolve, reject) => {
resolve(await foo);
});
Block misused of promise
π Examples of correct code
const promise = Promise.resolve('value');
// Always `await` the Promise in a conditional
if (await promise) {
// Do something
}
const val = (await promise) ? 123 : 456;
while (await promise) {
// Do something
}
π Examples of incorrect code
const promise = Promise.resolve('value');
// always true
if (promise) {
// Do something
}
const val = promise ? 123 : 456;
while (promise) {
// Do something
}
Enforces having one empty lines after the last top-level import statement or require call.
https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/newline-after-import.md
π Examples of correct code
import defaultExport from './foo'
const FOO = 'BAR'
// OR
import defaultExport from './foo'
import { bar } from 'bar-lib'
const FOO = 'BAR'
// OR
const FOO = require('./foo')
const BAR = require('./bar')
const BAZ = 1
π Examples of incorrect code
import * as foo from 'foo'
const FOO = 'BAR'
// OR
import * as foo from 'foo'
const FOO = 'BAR'
import { bar } from 'bar-lib'
// OR
const FOO = require('./foo')
const BAZ = 1
const BAR = require('./bar')
Reports use of a deprecated name, as indicated by a JSDoc block with a @deprecated tag or TomDoc Deprecated: comment.
https://github.com/import-js/eslint-plugin-import/blob/HEAD/docs/rules/no-deprecated.md
π Examples of correct code
π Examples of incorrect code
// @file: ./answer.js
/**
* this is what you get when you trust a mouse talk show
* @deprecated need to restart the experiment
* @returns {Number} nonsense
*/
export function multiply(six, nine) {
return 42
}
import { multiply } from './answer';
Forbids the use of mutable exports with var or let.
https://github.com/import-js/eslint-plugin-import/blob/HEAD/docs/rules/no-mutable-exports.md
π Examples of correct code
export const count = 1
export function getCount() {}
export class Counter {}
π Examples of incorrect code
export let count = 2
export var count = 3
let count = 4
export { count } // reported here
Reports require([array], ...) and define([array], ...) function calls at the module scope.
https://github.com/import-js/eslint-plugin-import/blob/HEAD/docs/rules/no-amd.md
π Examples of correct code
π Examples of incorrect code
define(["a", "b"], function (a, b) { /* ... */ })
require(["b", "c"], function (b, c) { /* ... */ })
When there is only a single export from a module, prefer using default export over named export.
https://github.com/import-js/eslint-plugin-import/blob/HEAD/docs/rules/prefer-default-export.md
π Examples of correct code
// There is a default export.
export const foo = 'foo';
const bar = 'bar';
export default bar;
// or
// good2.js
// There is more than one named export in the module.
export const foo = 'foo';
export const bar = 'bar';
// or
// good3.js
// There is more than one named export in the module
const foo = 'foo';
const bar = 'bar';
export { foo, bar }
// or
// good4.js
// There is a default export.
const foo = 'foo';
export { foo as default }
// or
// export-star.js
// Any batch export will disable this rule. The remote module is not inspected.
export * from './other-module'
π Examples of incorrect code
// There is only a single module export and it's a named export.
export const foo = 'foo';
Forbid modules to have too many dependencies (import or require statements).
https://github.com/import-js/eslint-plugin-import/blob/HEAD/docs/rules/max-dependencies.md
π Examples of correct code
import a from './a'; // 1
const b = require('./b'); // 2
// ...
import y from './y'; // 25 - No exceeds!
π Examples of incorrect code
import a from './a'; // 1
const b = require('./b'); // 2
// ...
import z from './z'; // 26 - exceeds max!
Reports the use of import declarations with CommonJS exports in any module except for the main module.
https://github.com/import-js/eslint-plugin-import/blob/HEAD/docs/rules/no-import-module-exports.md
π Examples of correct code
import thing from 'other-thing'
export default thing
const thing = require('thing')
module.exports = thing
const thing = require('thing')
exports.foo = bar
import thing from 'otherthing'
console.log(thing.module.exports)
// in lib/index.js
import foo from 'path';
module.exports = foo;
π Examples of incorrect code
import { stuff } from 'starwars'
module.exports = thing
import * as allThings from 'starwars'
exports.bar = thing
import thing from 'other-thing'
exports.foo = bar
import thing from 'starwars'
const baz = module.exports = thing
console.log(baz)
Use this rule to prevent unnecessary path segments in import and require statements.
https://github.com/import-js/eslint-plugin-import/blob/HEAD/docs/rules/no-useless-path-segments.md
π Examples of correct code
import "./header.js";
import "./pages";
import "./pages/about";
import ".";
import "..";
import fs from "fs";
π Examples of incorrect code
import "./../my-project/pages/about.js"; // should be "./pages/about.js"
import "./../my-project/pages/about"; // should be "./pages/about"
import "../my-project/pages/about.js"; // should be "./pages/about.js"
import "../my-project/pages/about"; // should be "./pages/about"
import "./pages//about"; // should be "./pages/about"
import "./pages/"; // should be "./pages"
import "./pages/index"; // should be "./pages" (except if there is a ./pages.js file)
import "./pages/index.js"; // should be "./pages" (except if there is a ./pages.js file)
Disable import dependencies if no exists in package.json dependencies
https://github.com/import-js/eslint-plugin-import/blob/HEAD/docs/rules/no-extraneous-dependencies.md
π Examples of correct code
import anything from "anything"; // exists in dependencies
π Examples of incorrect code
import typescript from "typescript"; // exists in dev dependency package.json
Enforce a convention in the order of require() / import statements Use: Alphabetic order import
https://github.com/import-js/eslint-plugin-import/blob/HEAD/docs/rules/order.md
π Examples of correct code
import fs from "fs"
import file from "./file";
import file2 from "./file2";
π Examples of incorrect code
import file from "./file";
import fs from "fs"
import file2 from "./file2";
Reports if a module's default export is unnamed.
π Examples of correct code
const foo = 123;
export default foo;
export default class MyClass() {};
export default function foo() {};
π Examples of incorrect code
export default []
export default () => {}
export default class {}
export default function () {}
export default 123
export default {}
export default new Foo()
Prefer using the node: protocol when importing Node.js builtin modules
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-node-protocol.md
π Examples of correct code
import dgram from 'node:dgram';
export {strict as default} from 'node:assert';
import fs from 'node:fs/promises';
const fs = require('fs');
import _ from 'lodash';
import fs from './fs.js';
const fs = require('node:fs/promises');
π Examples of incorrect code
import dgram from 'dgram';
export {strict as default} from 'assert';
import fs from 'fs/promises';
const fs = require('fs/promises');
Prefer exportβ¦from when re-exporting
When re-exporting from a module, it's unnecessary to import and then export. It can be done in a single exportβ¦from declaration.
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-export-from.md
π Examples of correct code
export {default} from './foo.js';
export {named} from './foo.js';
export * as namespace from './foo.js';
export {
default,
default as renamedDefault,
named,
named as renamedNamed,
} from './foo.js';
// There is no substitution
import * as namespace from './foo.js';
export default namespace;
π Examples of incorrect code
import defaultExport from './foo.js';
export default defaultExport;
import {named} from './foo.js';
export {named};
import * as namespace from './foo.js';
export {namespace};
import defaultExport, {named} from './foo.js';
export default defaultExport;
export {
defaultExport as renamedDefault,
named,
named as renamedNamed,
};
Prevent import empty
https://github.com/ODGodinho/ODG-Linter-Js
π Examples of correct code
import { a } from './foo.js';
import a from './foo.js';
π Examples of incorrect code
import { } from './foo.js';
import t, { } from './foo.js';
import type { } from './foo.js';
Ensure all exports appear after other statements.
https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/exports-last.md
π Examples of correct code
import { a } from './foo.js';
import a from './foo.js';
π Examples of incorrect code
import { } from './foo.js';
import t, { } from './foo.js';
This rule reports any imports that come after non-import statements.
https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/first.md
π Examples of correct code
import foo from './foo'
import bar from './bar' // <- reported
initWith(foo)
π Examples of incorrect code
import foo from './foo'
// some module-level initializer
initWith(foo)
import bar from './bar' // <- reported
Reports use of a default export as a locally named import.
https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-named-default.md
π Examples of correct code
import foo from './foo.js';
import foo, { bar } from './foo.js';
π Examples of incorrect code
// message: Using exported name 'bar' as identifier for default export.
import { default as foo } from './foo.js';
import { default as foo, bar } from './foo.js';
Require space after comment block.
Many style guides require empty lines before or after comments. The primary goal of these rules is to make the comments easier to read and improve readability of the code.
https://eslint.org/docs/rules/spaced-comment https://eslint.org/docs/latest/rules/lines-around-comment
π Examples of correct code
// This is a comment with a whitespace at the beginning
/* This is a comment with a whitespace at the beginning */
/*
* This is a comment with a whitespace at the beginning
*/
/**
* valid
*/
function() {}
π Examples of incorrect code
//This is a comment with no whitespace at the beginning
/*This is a comment with no whitespace at the beginning */
/**
* invalid after space
*/
function() {}
Require capitalization of the first letter of a comment.
https://eslint.org/docs/rules/capitalized-comments
π Examples of correct code
// Capitalized comment
// 1. Non-letter at beginning of comment
// δΈ Non-Latin character at beginning of comment
π Examples of incorrect code
// lowercase comment
Require alignment of JSDoc block asterisks.
https://github.com/gajus/eslint-plugin-jsdoc#user-content-eslint-plugin-jsdoc-rules-check-alignment
π Examples of correct code
/**
* @param {Number} foo
*/
π Examples of incorrect code
/**
* @param {Number} foo
*/
/**
* @param {Number} foo
*/
Disallow use space for align dockblock
https://github.com/gajus/eslint-plugin-jsdoc#user-content-eslint-plugin-jsdoc-rules-check-alignment
π Examples of correct code
/**
* @param {string} lorem Description.
* @param {int} sit Description multi words.
*/
π Examples of incorrect code
/**
* @param {string} lorem Description.
* @param {int} sit Description multi words.
*/
Check is valid @param and exists
https://github.com/gajus/eslint-plugin-jsdoc#check-param-names
π Examples of correct code
/**
* @param {string} a Description.
*/
foo(a) {
}
/**
* @param {string} a Description.
* @param {string} b Description.
*/
foo(a, b) {
}
π Examples of incorrect code
/**
* @param {string} b B iss not exists.
*/
foo(a) {
}
/**
* @param {string} b order is not correct
* @param {string} a
*/
foo(a, b) {
}
/**
* @param {string} a
* required b
*/
foo(a, b) {
}
Check is valid syntax docblock
https://github.com/gajus/eslint-plugin-jsdoc#check-syntax
π Examples of correct code
/**
* @param {string} foo
*/
function quux (foo) {
}
π Examples of incorrect code
/**
* @param {string=} foo
*/
function quux (foo) {
}
/**
* @param {string} [foo]
*/
function quux (foo) {
}
Check is valid tag docblock
https://github.com/gajus/eslint-plugin-jsdoc#check-tag-names
π Examples of correct code
/**
* @param
*/
π Examples of incorrect code
/**
* @notExistTag
*/
Check is valid type in docblock
https://github.com/gajus/eslint-plugin-jsdoc#check-types
π Examples of correct code
/**
* @param {string} a
*/
π Examples of incorrect code
/**
* @param {strings} a strings is not valid
*/
Check is valid values in docblock
https://github.com/gajus/eslint-plugin-jsdoc#check-values
π Examples of correct code
/**
* @version 1.0.0
*/
/**
* @version v1.0.0
*/
π Examples of incorrect code
/**
* @version v 1.0.0
*/
/**
* @version it's my version
*/
Require tags is empty
https://github.com/gajus/eslint-plugin-jsdoc#user-content-eslint-plugin-jsdoc-rules-empty-tags
π Examples of correct code
/**
* @global
*/
π Examples of incorrect code
/**
* @global this is global
*/
Disallow Extra asterisk in docblock
https://github.com/gajus/eslint-plugin-jsdoc#no-multi-asterisks
π Examples of correct code
/**
* bold text
*/
π Examples of incorrect code
/**
* *bold* text
*/
Disallow Extra asterisk in docblock
https://github.com/gajus/eslint-plugin-jsdoc#user-content-eslint-plugin-jsdoc-rules-no-defaults
π Examples of correct code
/**
* @param {number} foo
*/
function quux(foo) {
}
π Examples of incorrect code
/**
* @param {number} [foo="7"]
*/
function quux(foo) {
}
This rule reports elements that contradict an assertion. All elements reported by this rule fall into one of two categories:
https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-contradiction-with-assertion.html
π Examples of correct code
var foo = /a\b-a/;
var foo = /a\ba/; // handled by regexp/no-useless-assertions
π Examples of incorrect code
var foo = /a\b-?a/;
var foo = /a\b(a|-)/;
var foo = /a\ba*-/;
Control characters are special, invisible characters in the ASCII range 0-31. These characters are rarely used in JavaScript strings so a regular expression containing elements that explicitly match these characters is most likely a mistake.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-control-character.html
π Examples of correct code
var foo = /\n/;
var foo = RegExp("\n");
var pattern1 = /\x20/;
var pattern2 = /\u0020/;
var pattern3 = /\u{20}/u;
var pattern4 = /\t/;
var pattern5 = /\n/;
var pattern6 = new RegExp("\x20");
var pattern7 = new RegExp("\\t");
var pattern8 = new RegExp("\\n");
π Examples of incorrect code
var foo = /\x1f/;
var foo = /\x0a/;
var foo = RegExp('\x0a');
var pattern1 = /\x00/;
var pattern2 = /\x0C/;
var pattern3 = /\x1F/;
var pattern4 = /\u000C/;
var pattern5 = /\u{C}/u;
var pattern6 = new RegExp("\x0C"); // raw U+000C character in the pattern
var pattern7 = new RegExp("\\x0C"); // \x0C pattern
This rule disallows duplicate disjunctions.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-dupe-disjunctions.html
π Examples of correct code
const foo = /a|b/
const foo = /(a|b)/
const foo = /(?:a|b)/
π Examples of incorrect code
const foo = /a|a/
const foo = /(a|a)/
const foo = /(?:a|a)/
const foo = /abc|abc/
const foo = /[ab]|[ba]/
const foo = /a|abc/
const foo = /.|abc/
const foo = /.|a|b|c/
While (re-)writing long regular expressions, it can happen that one forgets to remove the | character of a former alternative. This rule tries to point out these potential mistakes by reporting all empty alternatives.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-empty-alternative.html
π Examples of correct code
var foo = /(?:)/
var foo = /a+|b*/
π Examples of incorrect code
var foo = /a+|b+|/
var foo = /\|\||\|||\|\|\|/
var foo = /a(?:a|bc|def|h||ij|k)/
This rule reports capturing group that captures assertions.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-empty-capturing-group.html
π Examples of correct code
var foo = /(?:)/
var foo = /a+|b*/
π Examples of incorrect code
var foo = /a+|b+|/
var foo = /\|\||\|||\|\|\|/
var foo = /a(?:a|bc|def|h||ij|k)/
This rule reports character classes that cannot match any characters.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-empty-character-class.html
π Examples of correct code
var foo = /abc[d]/;
var foo = /abc[a-z]/;
var foo = /[^]/;
var foo = /[\s\S]/;
π Examples of incorrect code
var foo = /abc[]/;
var foo = /[^\s\S]/;
This rule reports empty groups.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-empty-group.html
π Examples of correct code
var foo = /(a)/;
var foo = /(?:a)/;
π Examples of incorrect code
var foo = /()/;
var foo = /(|)/;
// non-capturing group
var foo = /(?:)/;
var foo = /(?:|)/;
This rule reports empty lookahead assertion or empty lookbehind assertion.
What are empty look around?
An empty look around is a look around for which at least one path in the look around expression contains only elements that do not consume characters and do not assert characters. This means that the look around expression will trivially accept any input string.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-empty-lookarounds-assertion.html
π Examples of correct code
var foo = /x(?=y)/;
var foo = /x(?!y)/;
var foo = /(?<=y)x/;
var foo = /(?<!y)x/;
π Examples of incorrect code
var foo = /x(?=)/;
var foo = /x(?!)/;
var foo = /(?<=)x/;
var foo = /(?<!)x/;
var foo = /(?=b?)\w/;
var foo = /(?!b?)\w/;
This rule reports [\b]. The word boundaries (\b) and the escape backspace ([\b]) are indistinguishable at a glance. This rule does not allow backspace ([\b]). Use unicode escapes (\u0008) instead.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-escape-backspace.html
π Examples of correct code
var foo = /\b/;
var foo = /\u0008/;
var foo = /\cH/;
var foo = /\x08/;
π Examples of incorrect code
var foo = /[\b]/;
This rule reports invalid regular expression patterns given to RegExp constructors.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-invalid-regexp.html
π Examples of correct code
RegExp('foo')
RegExp('[a' + ']')
π Examples of incorrect code
RegExp('\\')
RegExp('[a-Z]*')
RegExp('\\p{Foo}', 'u')
const space = '\\s*'
RegExp('=' + space + '+(\\w+)', 'u')
If a lazily quantified element is the last element matched by an expression (e.g. the a{2,3}? in b+a{2,3}?), we know that the lazy quantifier will always only match the element the minimum number of times. The maximum is completely ignored because the expression can accept after the minimum was reached.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-lazy-ends.html
π Examples of correct code
var foo = /a+?b*/.test(str)
var foo = /a??(?:ba+?|c)*/.test(str)
var foo = /ba*?$/.test(str)
π Examples of incorrect code
var foo = /a??/.test(str)
var foo = /a+b+?/.test(str)
var foo = /a(?:c|ab+?)?/.test(str)
This rule reports misleading Unicode characters.
Some Unicode characters like 'βοΈ', 'π§π·', and 'π¨βπ©βπ¦' consist of multiple code points. This causes problems in character classes and around quantifiers. E.g.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-misleading-unicode-character.html
π Examples of correct code
var foo = /π+/u;
var foo = /π¨βπ©βπ¦/;
π Examples of incorrect code
var foo = /π+/;
var foo = /[βοΈπ¨βπ©βπ¦]β€οΈ/;
Assertions that are quantified (directly or indirectly) can be considered optional if the quantifier has a minimum of zero.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-optional-assertion.html
π Examples of correct code
var foo = /\w+(?::|\b)/;
π Examples of incorrect code
var foo = /a(?:$)*b/;
var foo = /a(?:foo|(?<!-)(?:-|\b))*b/; // The `\b` is optional.
var foo = /(?:^)?\w+/; // warns about `^`
var foo = /\w+(?::|$)?/; // warns about `$`
If the referenced group of a backreference is not matched because some other path leads to the back-reference, the back-reference will trivially accept (e.g. /(?:(a)|b)\1/). The same will happen if the captured text of the referenced group was reset before reaching the back-reference.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-potentially-useless-backreference.html https://eslint.org/docs/latest/rules/no-useless-backreference
π Examples of correct code
var foo = /(a+)b\1/;
var foo = /(a+)b|\1/;
π Examples of incorrect code
var foo = /(?:(a)|b)\1/;
var foo = /(a)?b\1/;
var foo = /((a)|c)+b\2/;
Some assertion are unnecessary because the rest of the pattern forces them to always be accept (or reject).
https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-assertions.html
π Examples of correct code
var foo = /\bfoo\b/;
π Examples of incorrect code
var foo = /#\bfoo/; // \b will always accept
var foo = /foo\bbar/; // \b will always reject
var foo = /$foo/; // $ will always reject
var foo = /(?=\w)\d+/; // (?=\w) will always accept
Back references that will always trivially accept serve no function and can be removed.
This rule is a based on the ESLint core no-useless-back-reference rule. It reports all the ESLint core rule reports and some more.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-backreference.html
π Examples of correct code
var foo = /(a)b\1/;
var foo = /(a?)b\1/;
var foo = /(\b|a)+b\1/;
var foo = /(a)?(?:a|\1)/;
π Examples of incorrect code
var foo = /\1(a)/;
var foo = /(a\1)/;
var foo = /(a)|\1/;
var foo = /(?:(a)|\1)+/;
var foo = /(?<=(a)\1)/;
var foo = /(\b)a\1/;
This rule aims to detect and disallow useless $ replacements in regular expression replacements.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-dollar-replacements.html
π Examples of correct code
var newStr = str.replace(/(\w+)\s(\w+)/, '$2, $1');
// newStr = "Smith, John"
var newStr = str.replace(/(?<first>\w+)\s(?<last>\w+)/, '$<last>, $<first>');
// newStr = "Smith, John"
'123456789012'.replaceAll(/(.)../g, '$1**'); // "1**4**7**0**"
π Examples of incorrect code
var newStr = str.replace(/(\w+)\s(\w+)/, '$3, $1 $2');
// newStr = "$3, John Smith"
var newStr = str.replace(/(?<first>\w+)\s(?<last>\w+)/, '$<last>, $<first> $<middle>');
// newStr = "Smith, John "
var newStr = str.replace(/(\w+)\s(\w+)/, '$<last>, $<first>');
// newStr = "$<last>, $<first>"
This rule disallows not strictly valid regular expressions.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/strict.html
π Examples of correct code
var foo = /\}/
var foo = /\{/
var foo = /\]/
var foo = /\u{42}/u; // It matches "B".
var foo = /u{42}/; // It matches a string followed by 42 "u"s.
π Examples of incorrect code
var foo = /}/
var foo = /{/
var foo = /]/
var foo = /\u{42}/; // It matches a string followed by 42 "u"s.
Confusing quantifiers are ones which imply one thing but don't deliver on that.
An example of this is (?:a?b*|c+){4}. The group is quantified with {4} which implies that at least 4 characters will be matched but this is not the case. The whole pattern will match the empty string. It does that because in the a?b* alternative, it's possible to choose 0 many a and b. So rather than {4}, {0,4} should be used to reflect the fact that the empty string can be matched.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/confusing-quantifier.html
π Examples of correct code
var foo = /a*/;
var foo = /(a|b|c)+/;
var foo = /a?/;
π Examples of incorrect code
var foo = /(a?){4}/; // warns about `{4}`
var foo = /(a?b*)+/; // warns about `+`
This rule reports control characters that were not escaped using a control escape (\0, t, \n, \v, f, \r).
https://ota-meshi.github.io/eslint-plugin-regexp/rules/control-character-escape.html
π Examples of correct code
var foo = /[\n\r]/;
var foo = /\t/;
var foo = RegExp("\t+\n");
π Examples of incorrect code
var foo = / /;
var foo = /\u0009/;
var foo = /\u{a}/u;
var foo = RegExp("\\u000a");
This rule enforces use of \D, \W, \S and \P on negation.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/negation.html
π Examples of correct code
var foo = /\D/
var foo = /\W/
var foo = /\S/
var foo = /\P{ASCII}/u
var foo = /\d/
var foo = /\w/
var foo = /\s/
var foo = /\p{ASCII}/u
π Examples of incorrect code
var foo = /[^\d]/
var foo = /[^\w]/
var foo = /[^\s]/
var foo = /[^\p{ASCII}]/u
var foo = /[^\D]/
var foo = /[^\W]/
var foo = /[^\S]/
var foo = /[^\P{ASCII}]/u
Because multiple same character classes in regular expressions only one is useful, they might be typing mistakes.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-dupe-characters-character-class.html
π Examples of correct code
var foo = /[\(\)]/;
var foo = /[a-z\s]/;
var foo = /[\w]/;
π Examples of incorrect code
var foo = /[\\(\\)]/;
// ^^ ^^ "\\" are duplicated
var foo = /[a-z\\s]/;
// ^^^ ^ "s" are duplicated
var foo = /[\w0-9]/;
// ^^^^^ "0-9" are duplicated
This rule disallows using invisible characters other than SPACE (U+0020) without using escapes.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-invisible-character.html
π Examples of correct code
var foo = /\t/;
var foo = /\v/;
var foo = /\f/;
var foo = /\u3000/;
var foo = / /; // SPACE (`U+0020`)
π Examples of incorrect code
// \u000B - Line Tabulation (\v) - <VT>
// \u000C - Form Feed (\f) - <FF>
// \u00A0 - No-Break Space - <NBSP>
// \u0085 - Next Line
// \u1680 - Ogham Space Mark
// \u180E - Mongolian Vowel Separator - <MVS>
// \ufeff - Zero Width No-Break Space - <BOM>
// \u2000 - En Quad
// \u2001 - Em Quad
// \u2002 - En Space - <ENSP>
// \u2003 - Em Space - <EMSP>
// \u2004 - Three-Per-Em
// \u2005 - Four-Per-Em
// \u2006 - Six-Per-Em
// \u2007 - Figure Space
// \u2008 - Punctuation Space - <PUNCSP>
// \u2009 - Thin Space
// \u200A - Hair Space
// \u200B - Zero Width Space - <ZWSP>
// \u2028 - Line Separator
// \u2029 - Paragraph Separator
// \u202F - Narrow No-Break Space
// \u205f - Medium Mathematical Space
// \u3000 - Ideographic Space
This rule disallow legacy RegExp features.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-legacy-features.html
π Examples of correct code
π Examples of incorrect code
RegExp.input
RegExp.$_
RegExp.lastMatch
RegExp["$&"]
RegExp.lastParen
RegExp["$+"]
RegExp.leftContext
RegExp["$`"]
RegExp.rightContext
RegExp["$'"]
RegExp.$1
RegExp.$2
RegExp.$3
RegExp.$4
RegExp.$5
RegExp.$6
RegExp.$7
RegExp.$8
RegExp.$9
const regexObj = new RegExp('foo', 'gi');
regexObj.compile('new foo', 'g');
This rule reports non-standard flags.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-non-standard-flag.html
π Examples of correct code
var foo = /a*b*c/guy;
π Examples of incorrect code
var foo = RegExp("a*b*c", "l"); // L don1t exists
The character range operator (the - inside character classes) can easily be misused (mostly unintentionally) to construct non-obvious character class. This rule will disallow all non-obvious uses of the character range operator.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-obscure-range.html
π Examples of correct code
var foo = /[a-z]/;
var foo = /[J-O]/;
var foo = /[1-9]/;
var foo = /[\x00-\x40]/;
var foo = /[\0-\uFFFF]/;
var foo = /[\0-\u{10FFFF}]/u;
var foo = /[\1-\5]/;
var foo = /[\cA-\cZ]/;
π Examples of incorrect code
var foo = /[A-\x43]/;
var foo = /[\41-\x45]/;
var foo = /[!-$]/;
var foo = /[π-π]/u;
The character range operator (the - inside character classes) can easily be misused (mostly unintentionally) to construct non-obvious character class. This rule will disallow all non-obvious uses of the character range operator.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-obscure-range.html
π Examples of correct code
var foo = /[a-z]/;
var foo = /[J-O]/;
var foo = /[1-9]/;
var foo = /[\x00-\x40]/;
var foo = /[\0-\uFFFF]/;
var foo = /[\0-\u{10FFFF}]/u;
var foo = /[\1-\5]/;
var foo = /[\cA-\cZ]/;
π Examples of incorrect code
var foo = /[A-\x43]/;
var foo = /[\41-\x45]/;
var foo = /[!-$]/;
var foo = /[π-π]/u;
This rule reports unused capturing groups.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-unused-capturing-group.html
π Examples of correct code
var matches = '2000-12-31 2001-01-01'.match(/(\d{4})-(\d{2})-(\d{2})/)
var y = matches[1] // "2000"
var m = matches[2] // "12"
var d = matches[3] // "31"
π Examples of incorrect code
var isDate = /(\d{4})-(\d{2})-(\d{2})/.test('2000-12-31') // true But group never used
This rule reports character classes that defines only one character.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-character-class.html
π Examples of correct code
var foo = /abc/;
π Examples of incorrect code
var foo = /a[b]c/;
This will point out present regex flags that do not change the pattern.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-character-class.html
π Examples of correct code
var foo = /a|b/i;
var foo = /^foo$/m;
var foo = /a.*?b/s;
const regex1 = /foo/y;
const str = 'table football, football';
regex1.lastIndex = 6
var array = regex1.exec(str)
π Examples of incorrect code
var foo = /\.{3}/i;
var foo = /\w+/i;
var foo = /foo|[^\r\n]*/m;
var foo = /a|b/m;
var foo = /[.:]/s;
var foo = /^foo$/s;
str.split(/foo/y);
This rule reports lazy quantifiers that don't need to by lazy.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-lazy.html
π Examples of correct code
var foo = /a*?/;
var foo = /a+?/;
var foo = /a{4,}?/;
var foo = /a{2,4}?/;
var foo = /a[\s\S]*?bar/;
π Examples of incorrect code
var foo = /a{1}?/;
var foo = /a{4}?/;
var foo = /a{2,2}?/;
var foo = /ab+?c/;
This rule reports quantifiers that can trivially be removed without affecting the pattern.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-quantifier.html
π Examples of correct code
var foo = /a*/;
var foo = /(?:a|b?)??/;
var foo = /(?:\b|(?!a))*/;
π Examples of incorrect code
var foo = /a{1}/;
var foo = /(?:\b)+/;
var foo = /(?:a+b*|c*)?/;
This rule reports unnecessary range of characters by using a hyphen. e.g. [a-a]
https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-range.html
π Examples of correct code
var foo = /[a]/
var foo = /[ab]/
π Examples of incorrect code
var foo = /[a-a]/
var foo = /[a-b]/
This rule reports unnecessary {n,m} quantifiers.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-two-nums-quantifier.html
π Examples of correct code
var foo = /a{0,1}/;
var foo = /a{1,5}/;
var foo = /a{1,}/;
var foo = /a{2}/;
π Examples of incorrect code
var foo = /a{0,0}/;
var foo = /a{1,1}/;
var foo = /a{2,2}/;
This rule reports quantifiers with a maximum of zero. These quantifiers trivially do not affect the pattern is any way and can be removed.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-zero-quantifier.html
π Examples of correct code
var foo = /a?/;
var foo = /a{0,}/;
var foo = /a{0,1}/;
π Examples of incorrect code
var foo = /a{0}/;
var foo = /a{0,0}?/;
var foo = /(a){0}/;
Non-constant quantifiers are quantifiers that describe a range.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/optimal-lookaround-quantifier.html
π Examples of correct code
// lookaheads
var foo = /\w+(?=\s*:)/;
// lookbehinds
var foo = /(?<=ab+)/;
π Examples of incorrect code
// lookaheads
var foo = /(?=ab+)/; // == /(?=ab)/
var foo = /(?=ab*)/; // == /(?=a)/
var foo = /(?!ab?)/; // == /(?!a)/
var foo = /(?!ab{6,})/; // == /(?!ab{6})/
// lookbehinds
var foo = /(?<=a+b)/; // == /(?<=ab)/
var foo = /(?<!\w*\s*,)/; // == /(?<!,)/
If two quantified characters, character classes, or characters are concatenated, the quantifiers can be optimized if either of the characters elements is a subset of the other.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/optimal-lookaround-quantifier.html
π Examples of correct code
var foo = /\w+\d{4}/;
var foo = /\w{3,5}\d*/;
var foo = /a+b+c+d+[abc]+/;
var foo = /a\w*/;
π Examples of incorrect code
var foo = /\w+\d+/;
var foo = /\w+\d?/;
var foo = /[ab]*(?:a|b)/;
var foo = /\w+(?:(a)|b)*/;
This rule is aimed to use quantifiers instead of consecutive characters in regular expressions.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/optimal-lookaround-quantifier.html
π Examples of correct code
var foo = /\d{4}-\d{2}-\d{2}/;
π Examples of incorrect code
var foo = /\d\d\d\d-\d\d-\d\d/;
This rule is aimed to use ranges instead of multiple adjacent characters in character class.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-range.html
π Examples of correct code
var foo = /[0-9]/
var foo = /[a-f]/
π Examples of incorrect code
var foo = /[123456789]/
var foo = /[a-cd-f]/
This rule will only sort alternatives if reordering the alternatives doesn't affect the pattern.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/sort-alternatives.html
π Examples of correct code
var foo = /\b(1|2|3)\b/;
var foo = /\b(alpha|beta|gamma)\b/;
π Examples of incorrect code
var foo = /\b(2|1|3)\b/;
var foo = /__(?:Foo|Bar)__/;
var foo = /\((?:TM|R|C)\)/;
This rule aims is enforces the consistent use of hexadecimal escapes.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/hexadecimal-escape.html
π Examples of correct code
var foo = /\x0a/;
π Examples of incorrect code
var foo = /\u000a/;
var foo = /\u{a}/u;
This rule enforces the regular expression notation to match any character.
e.g. [\s\S], [^], /./s
(dotAll) and more.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/match-any.html
π Examples of correct code
var foo = /[\s\S]/;
var foo = /./s;
π Examples of incorrect code
var foo = /[\S\s]/;
var foo = /[^]/;
var foo = /[\d\D]/;
var foo = /[\w\W]/;
This rule reports unnecessary escape characters in RegExp. You may be able to find another mistake by finding unnecessary escapes.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-escape.html
π Examples of correct code
var foo = /\[/
var foo = /\\/
π Examples of incorrect code
var foo = /\a/
var foo = /\x7/
var foo = /\u41/
var foo = /\u{[41]}/
This rule reports unnecessary non-capturing group
https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-character-class.html
π Examples of correct code
var foo = /(?:abcd)?/.test(str)
var foo = /a(?:ab|cd)/.test(str)
π Examples of incorrect code
var foo = /(?:ab|cd)/.test(str)
var foo = /(?:abcd)/.test(str)
var foo = /(?:[a-d])/.test(str)
var foo = /(?:[a-d])|e/.test(str)
var foo = /(?:a|(?:b|c)|d)/.test(str)
Instead of single-character alternatives (e.g. (?:a|b|c)),character classes (e.g. [abc]) should be preferred.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-non-capturing-group.html
π Examples of correct code
var foo = /[abc]/
var foo = /(?:a|b)/
π Examples of incorrect code
var foo = /a|b|c/
var foo = /(a|b|c)c/
var foo = /.|\s/
var foo = /(\w|\d)+:/
This rule is aimed at using \d instead of [0-9] in regular expressions.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-d.html
π Examples of correct code
var foo = /\d/;
var foo = /\D/;
π Examples of incorrect code
var foo = /[0-9]/;
var foo = /[^0-9]/;
This rule is aimed at using + quantifier instead of {1,} in regular expressions.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-plus-quantifier.html
π Examples of correct code
var foo = /a+/;
π Examples of incorrect code
var foo = /a{1,}/;
This rule is aimed at using ? quantifier instead of {0,1} in regular expressions.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-question-quantifier.html
π Examples of correct code
var foo = /a?/;
π Examples of incorrect code
var foo = /a{0,1}/;
This rule is aimed at using * quantifier instead of {0,} in regular expressions.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-star-quantifier.html
π Examples of correct code
var foo = /a*/
π Examples of incorrect code
var foo = /a{0,}/;
This rule enforces the use of Unicode codepoint escapes instead of Unicode escapes using surrogate pairs.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-unicode-codepoint-escapes.html
π Examples of correct code
var foo = /\u{1f600}/u
var foo = /π/u
π Examples of incorrect code
var foo = /\ud83d\ude00/u
This rule is aimed at using \w in regular expressions.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-w.html
π Examples of correct code
var foo = /\w/;
var foo = /\W/;
π Examples of incorrect code
var foo = /[0-9a-zA-Z_]/;
var foo = /[^0-9a-zA-Z_]/;
var foo = /[0-9a-z_]/i;
var foo = /[0-9a-z_-]/i;
This rule checks elements of character classes are sorted.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/sort-character-class-elements.html
π Examples of correct code
var foo = /[abcdef]/
var foo = /[ab-f]/
π Examples of incorrect code
var foo = /[bcdefa]/
var foo = /[b-fa]/
The flags of JavaScript regular expressions should be sorted alphabetically because the flags of the
.flags
property of RegExp
objects are always sorted.
Not sorting flags in regex literals misleads readers into thinking
that the order may have some purpose which it doesn't.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/sort-flags.html
π Examples of correct code
var foo = /abc/
var foo = /abc/iu
var foo = /abc/gimsuy
π Examples of incorrect code
var foo = /abc/mi
var foo = /abc/us
This rule reports capturing groups without a name.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-named-capture-group.html
π Examples of correct code
var foo = /(?<foo>ba+r)/;
var foo = /\b(?:foo)+\b/;
π Examples of incorrect code
var foo = /\b(foo)+\b/;
RegExp#exec is faster than String#match and both work the same when not using the /g flag.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-regexp-exec.html https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/prefer-regexp-exec.md
π Examples of correct code
/thing/.exec('something');
'some things are just things'.match(/thing/g);
const text = 'something';
const search = /thing/;
search.exec(text);
π Examples of incorrect code
'something'.match(/thing/);
'some things are just things'.match(/thing/);
const text = 'something';
const search = /thing/;
text.match(search);
Replacement strings should reference existing regular expression groups
https://sonarsource.github.io/rspec/#/rspec/S6328/javascript
π Examples of correct code
const str = 'James Bond';
console.log(str.replace(/(\w+)\s(\w+)/, '$1, $0 $1'));
console.log(str.replace(/(?<firstName>\w+)\s(?<lastName>\w+)/, '$<surname>, $<firstName> $<surname>'));
π Examples of incorrect code
const str = 'James Bond';
console.log(str.replace(/(\w+)\s(\w+)/, '$2, $1 $2'));
console.log(str.replace(/(?<firstName>\w+)\s(?<lastName>\w+)/, '$<lastName>, $<firstName> $<lastName>'));
This rule reports capturing groups that capture less text than their pattern might suggest.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-misleading-capturing-group.html
π Examples of correct code
var foo = /a+(b*)/
π Examples of incorrect code
var foo = /a+(a*)/
var foo = /\w+(\d*)/
var foo = /^(a*).+/
The last positive lookahead assertion within a lookahead assertion is the same without lookahead assertions. Also, The first positive lookbehind assertion within a lookbehind assertion is the same without lookbehind assertions. They can be inlined or converted to group.
https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-extra-lookaround-assertions.html
π Examples of correct code
var ts = 'JavaScript'.replace(/Java(?=Script)/u, 'Type');
var java = 'JavaScript'.replace(/(?<=Java)Script/u, '');
var re1 = /a(?=bc)/u;
var re2 = /a(?=b(?:c|C))/u;
var re3 = /(?<=ab)c/u;
var re4 = /(?<=(?:a|A)b)c/u;
π Examples of incorrect code
var ts = 'JavaScript'.replace(/Java(?=Scrip(?=t))/u, 'Type');
var java = 'JavaScript'.replace(/(?<=(?<=J)ava)Script/u, '');
var re1 = /a(?=b(?=c))/u;
var re2 = /a(?=b(?=c|C))/u;
var re3 = /(?<=(?<=a)b)c/u;
var re4 = /(?<=(?<=a|A)b)c/u;
JavaScript's eval() function is potentially dangerous and is often misused. Using eval() on untrusted code can open a program up to several different injection attacks. The use of eval() in most contexts can be substituted for a better, alternative approach to a problem. Disallow the use of eval()-like methods
https://eslint.org/docs/rules/no-eval#no-eval https://eslint.org/docs/rules/no-implied-eval https://sonarsource.github.io/rspec/#/rspec/S1523/javascript https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/no-implied-eval.md
π Examples of correct code
var obj = { x: "foo" },
key = "x",
value = obj[key];
class A {
foo() {
// This is a user-defined method.
this.eval("var a = 0");
}
eval() {
}
static {
// This is a user-defined static method.
this.eval("var a = 0");
}
static eval() {
}
}
π Examples of incorrect code
var obj = { x: "foo" },
key = "x",
value = eval("obj." + key);
(0, eval)("var a = 0");
var foo = eval;
foo("var a = 0");
// This `this` is the global object.
this.eval("var a = 0");
There are many ways to block the event loop, one way an attacker can do that is with Regular Expression Denial of Service (ReDoS).
π Examples of correct code
var expression = /^[\w+\-.]+@[\d\-A-Za-z]+\.[\d\-.A-Za-z]+$/
π Examples of incorrect code
var expression = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
Detect calls to buffer with noAssert flag set.
From the Node.js API docs: "Setting noAssert to true skips validation of the offset. This allows the offset to be beyond the end of the Buffer."
https://github.com/nodesecurity/eslint-plugin-security#detect-buffer-noassert
π Examples of correct code
π Examples of incorrect code
/** https://nodejs.org/api/buffer.html */
Detect instances of child_process & non-literal exec()
π Examples of correct code
var child_process = require('child_process');
var path = '.';
child_process.execFile('/bin/ls', ['-l', path], function (err, result) {
console.log(result);
});
// Or
var child_process = require('child_process');
var path = '.';
var ls = child_process.spawn('/bin/ls', ['-l', path]);
ls.stdout.on('data', function (data) {
console.log(data.toString());
});
π Examples of incorrect code
var path = 'user input';
child_process.exec('ls -l ' + path, function (err, data) {
console.log(data);
});
Detects object.escapeMarkup = false, which can be used with some template engines to disable escaping of HTML entities. This can lead to Cross-Site Scripting (XSS) vulnerabilities.
More information: OWASP XSS
https://github.com/nodesecurity/eslint-plugin-security#detect-disable-mustache-escape
π Examples of correct code
// No remove object.escapeMarkup = false
π Examples of incorrect code
object.escapeMarkup = false
As the declaration order of middlewares determines the execution stack in Connect, it is possible to abuse this functionality in order to bypass the standard Connect's anti-CSRF protection.
π Examples of correct code
app.use(express.csrf())
app.use(express.methodOverride())
π Examples of incorrect code
app.use(express.methodOverride())
app.use(express.csrf())
Detects variable in filename argument of fs calls, which might allow an attacker to access anything on your system.
https://github.com/nodesecurity/eslint-plugin-security#detect-non-literal-fs-filename
π Examples of correct code
π Examples of incorrect code
Detects if pseudoRandomBytes() is in use, which might not give you the randomness you need and expect.
https://github.com/nodesecurity/eslint-plugin-security#detect-non-literal-fs-filename https://sonarsource.github.io/rspec/#/rspec/S2245/javascript
π Examples of correct code
var crypto = require("crypto")
const random = crypto.randomBytes(60);
π Examples of incorrect code
const random = Math.random();
Prevent commit with token, passwords, keys etc.
π Examples of correct code
const apiKey = process.env.apiKey;
π Examples of incorrect code
const apiKey = "123456"
Prevent attack in your code
π Examples of correct code
require('../name');
require(`../name`);
π Examples of incorrect code
require(name);
require('../' + name);
require(`../${name}`);
require(name());
This rule checks every call to require() that uses expressions for the module name argument.
https://github.com/import-js/eslint-plugin-import/blob/HEAD/docs/rules/no-dynamic-require.md
π Examples of correct code
require('../name');
require(`../name`);
π Examples of incorrect code
require(name);
require('../' + name);
require(`../${name}`);
require(name());
Authorizing HTTP communications with S3 buckets is security-sensitive
https://sonarsource.github.io/rspec/#/rspec/S6249/javascript
π Examples of correct code
const s3 = require('aws-cdk-lib/aws-s3');
const bucket = new s3.Bucket(this, 'example', {
bucketName: 'example',
versioned: true,
publicReadAccess: false,
enforceSSL: true
});
π Examples of incorrect code
const s3 = require('aws-cdk-lib/aws-s3');
const bucket = new s3.Bucket(this, 'example'); // Sensitive
Allowing public ACLs or policies on a S3 bucket is security-sensitive Disabling server-side encryption of S3 buckets is security-sensitive
By default S3 buckets are private, it means that only the bucket owner can access it. This access control can be relaxed with ACLs or policies. To prevent permissive policies or ACLs to be set on a S3 bucket the following booleans settings can be enabled:
https://sonarsource.github.io/rspec/#/rspec/S6281/javascript https://sonarsource.github.io/rspec/#/rspec/S6245/javascript
π Examples of correct code
const s3 = require('aws-cdk-lib/aws-s3');
new s3.Bucket(this, 'id', {
bucketName: 'bucket',
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL
});
new s3.Bucket(this, 'id', {
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
encryption: s3.BucketEncryption.KMS_MANAGED
});
# Alternatively with a KMS key managed by the user.
new s3.Bucket(this, 'id', {
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
encryption: s3.BucketEncryption.KMS_MANAGED,
encryptionKey: access_key
});
π Examples of incorrect code
const s3 = require('aws-cdk-lib/aws-s3');
new s3.Bucket(this, 'id', {
bucketName: 'bucket'
}); // Sensitive
Disabling Certificate Transparency monitoring is security-sensitive
Implement Expect-CT HTTP header which instructs the web browser to check public CT logs in order to verify if the website appears inside and if it is not, the browser will block the request and display a warning to the user.
https://sonarsource.github.io/rspec/#/rspec/S5742/javascript
π Examples of correct code
const express = require('express');
const helmet = require('helmet');
let app = express();
app.use(helmet.expectCt({
enforce: true,
maxAge: 86400
})); // Compliant
π Examples of incorrect code
const express = require('express');
const helmet = require('helmet');
let app = express();
app.use(
helmet({
expectCt: false // Sensitive
})
);
Log management is an important topic, especially for the security of a web application, to ensure user activity, including potential attackers, is recorded and available for an analyst to understand whatβs happened on the web application in case of malicious activities.
https://sonarsource.github.io/rspec/#/rspec/S5757/javascript
π Examples of correct code
const { Signale } = require('signale');
const CREDIT_CARD_NUMBERS = fetchFromWebForm()
// here we suppose the credit card numbers are retrieved somewhere and CREDIT_CARD_NUMBERS looks like
// ["1234-5678-0000-9999", "1234-5678-0000-8888"]; for instance
const options = {
secrets: ["([0-9]{4}-?)+"]
};
const logger = new Signale(options); // Compliant
CREDIT_CARD_NUMBERS.forEach(function(CREDIT_CARD_NUMBER) {
logger.log('The customer ordered products with the credit card number = %s', CREDIT_CARD_NUMBER);
});
π Examples of incorrect code
const { Signale } = require('signale');
const CREDIT_CARD_NUMBERS = fetchFromWebForm()
// here we suppose the credit card numbers are retrieved somewhere and CREDIT_CARD_NUMBERS looks like
// ["1234-5678-0000-9999", "1234-5678-0000-8888"]; for instance
const options = {
secrets: [] // empty list of secrets
};
const logger = new Signale(options); // Sensitive
CREDIT_CARD_NUMBERS.forEach(function(CREDIT_CARD_NUMBER) {
logger.log('The customer ordered products with the credit card number = %s', CREDIT_CARD_NUMBER);
});
Rejecting requests with significant content length is a good practice to control the network traffic intensity and thus resource consumption in order to prevents DoS attacks.
https://sonarsource.github.io/rspec/#/rspec/S5693/javascript
π Examples of correct code
const form = new Formidable();
form.maxFileSize = 8000000; // Compliant: 8MB
let diskUpload = multer({
storage: diskStorage,
limits: {
fileSize: 8000000 // Compliant: 8MB
}
});
let jsonParser = bodyParser.json(); // Compliant, when the limit is not defined, the default value is set to 100kb
let urlencodedParser = bodyParser.urlencoded({ extended: false, limit: "2mb" }); // Compliant
π Examples of incorrect code
const form = new Formidable();
form.maxFileSize = 10000000; // Sensitive: 10MB is more than the recommended limit of 8MB
const formDefault = new Formidable(); // Sensitive, the default value is 200MB
let diskUpload = multer({
storage: diskStorage,
limits: {
fileSize: 10000000; // Sensitive: 10MB is more than the recommended limit of 8MB
}
});
let diskUploadUnlimited = multer({ // Sensitive: the default value is no limit
storage: diskStorage,
});
// 4MB is more than the recommended limit of 2MB for non-file-upload requests
let jsonParser = bodyParser.json({ limit: "4mb" }); // Sensitive
let urlencodedParser = bodyParser.urlencoded({ extended: false, limit: "4mb" }); // Sensitive
The trick is to use Unicode control characters to reorder tokens in source code at the encoding level. These visually reordered tokens can be used to display logic that, while semantically correct, diverges from the logic presented by the logical ordering of source code tokens.
https://trojansource.codes/ https://github.com/lirantal/eslint-plugin-anti-trojan-source https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-bidi-characters.md
When a cookie is configured with the HttpOnly attribute set to true, the browser guaranties that no client-side script will be able to read it. In most cases, when a cookie is created, the default value of HttpOnly is false and itβs up to the developer to decide whether or not the content of the cookie can be read by the client-side script. As a majority of Cross-Site Scripting (XSS) attacks target the theft of session-cookies, the HttpOnly attribute can help to reduce their impact as it wonβt be possible to exploit the XSS vulnerability to steal session-cookies.
https://sonarsource.github.io/rspec/#/rspec/S3330/javascript https://sonarsource.github.io/rspec/#/rspec/S2255/javascript
let session = cookieSession({
httpOnly: true,// Compliant
}); // Compliant
const express = require('express');
const session = require('express-session');
let app = express();
app.use(session({
cookie:
{
httpOnly: true // Compliant
}
}));
let cookies = new Cookies(req, res, { keys: keys });
cookies.set('LastVisit', new Date().toISOString(), {
httpOnly: true // Compliant
}); // Compliant
const cookieParser = require('cookie-parser');
const csrf = require('csurf');
const express = require('express');
let csrfProtection = csrf({ cookie: { httpOnly: true }}); // Compliant
π Examples of incorrect code
let session = cookieSession({
httpOnly: false,// Sensitive
}); // Sensitive
const express = require('express');
const session = require('express-session');
let app = express()
app.use(session({
cookie:
{
httpOnly: false // Sensitive
}
}));
let cookies = new Cookies(req, res, { keys: keys });
cookies.set('LastVisit', new Date().toISOString(), {
httpOnly: false // Sensitive
}); // Sensitive
const cookieParser = require('cookie-parser');
const csrf = require('csurf');
const express = require('express');
let csrfProtection = csrf({ cookie: { httpOnly: false }}); // Sensitive
Disabling auto-escaping in template engines is security-sensitive
https://sonarsource.github.io/rspec/#/rspec/S5247/javascript
let Mustache = require("mustache");
let rendered = Mustache.render(template, { name: inputName });
// or
const Handlebars = require('handlebars');
let source = "<p>attack {{name}}</p>";
let data = { "name": "<b>Alan</b>" };
let template = Handlebars.compile(source);
// or
let md = require('markdown-it')();
let result = md.render('# <b>attack</b>');
// or
const marked = require('marked');
marked.setOptions({
renderer: new marked.Renderer()
}); // Compliant by default sanitize is set to true
console.log(marked("# test <b>attack/b>"));
// or
let kramed = require('kramed');
let options = {
renderer: new kramed.Renderer({
sanitize: true // Compliant
})
};
console.log(kramed('Attack [xss?](javascript:alert("xss")).', options));
π Examples of incorrect code
let Mustache = require("mustache");
Mustache.escape = function(text) {return text;}; // Sensitive
let rendered = Mustache.render(template, { name: inputName });
// or
const Handlebars = require('handlebars');
let source = "<p>attack {{name}}</p>";
let template = Handlebars.compile(source, { noEscape: true }); // Sensitive
// or
const markdownIt = require('markdown-it');
let md = markdownIt({
html: true // Sensitive
});
let result = md.render('# <b>attack</b>');
// or
const marked = require('marked');
marked.setOptions({
renderer: new marked.Renderer(),
sanitize: false // Sensitive
});
console.log(marked("# test <b>attack/b>"));
// or
let kramed = require('kramed');
var options = {
renderer: new kramed.Renderer({
sanitize: false // Sensitive
})
};
Disabling resource integrity features is security-sensitive
Fetching external resources, for example from a CDN, without verifying their integrity could impact the security of an application if the CDN gets compromised and resources are replaced by malicious ones. Resources integrity feature will block resources inclusion into an application if the pre-computed digest of the expected resource doesnβt match with the digest of the retrieved resource.
https://sonarsource.github.io/rspec/#/rspec/S5725/javascript
let script = document.createElement("script");
script.src = "https://cdnexample.com/script-v1.2.3.js";
script.integrity = "sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"; // Compliant
script.crossOrigin = "anonymous";
document.head.appendChild(script);
π Examples of incorrect code
let script = document.createElement("script");
script.src = "https://cdnexample.com/script-latest.js";
// Sensitive no integrity
script.crossOrigin = "anonymous";
document.head.appendChild(script);
Allowing browsers to perform DNS prefetching is security-sensitive
https://sonarsource.github.io/rspec/#/rspec/S5743/javascript
const express = require('express');
const helmet = require('helmet');
let app = express();
app.use(
helmet.dnsPrefetchControl({
allow: false // Compliant
})
);
π Examples of incorrect code
const express = require('express');
const helmet = require('helmet');
let app = express();
app.use(
helmet.dnsPrefetchControl({
allow: true // Sensitive: allowing DNS prefetching is security-sensitive
})
);
Additionally, objects can have properties that shadow the builtins on Object.prototype, potentially causing unintended behavior or denial-of-service security vulnerabilities. For example, it would be unsafe for a webserver to parse JSON input from a client and call hasOwnProperty directly on the resulting object, because a malicious client could send a JSON value like {"hasOwnProperty": 1} and cause the server to crash.
To avoid subtle bugs like this, itβs better to always call these methods from Object.prototype. For example, foo.hasOwnProperty("bar") should be replaced with Object.prototype.hasOwnProperty.call(foo, "bar").
https://eslint.org/docs/latest/rules/No-Prototype-Builtins
var hasBarProperty = Object.prototype.hasOwnProperty.call(foo, "bar");
var isPrototypeOfBar = Object.prototype.isPrototypeOf.call(foo, bar);
var barIsEnumerable = {}.propertyIsEnumerable.call(foo, "bar");
π Examples of incorrect code
var hasBarProperty = foo.hasOwnProperty("bar");
var isPrototypeOfBar = foo.isPrototypeOf(bar);
var barIsEnumerable = foo.propertyIsEnumerable("bar");
Setting loose POSIX file permissions is security-sensitive Dont use 777
https://sonarsource.github.io/rspec/#/rspec/S2612/javascript
const fs = require('fs');
fs.chmodSync("/tmp/fs", 0o770); // Compliant
// OR
const fs = require('fs');
const fsPromises = fs.promises;
fsPromises.chmod("/tmp/fsPromises", 0o770); // Compliant
π Examples of incorrect code
const fs = require('fs');
fs.chmodSync("/tmp/fs", 0o777); // Sensitive
// OR
const fs = require('fs');
const fsPromises = fs.promises;
fsPromises.chmod("/tmp/fsPromises", 0o777); // Sensitive
These minimum restrictions should be applied when handling file uploads:
https://sonarsource.github.io/rspec/#/rspec/S2598/javascript
const Formidable = require('formidable');
const form = new Formidable(); // Compliant
form.uploadDir = "./uploads/";
form.keepExtensions = false;
π Examples of incorrect code
const Formidable = require('formidable');
const form = new Formidable(); // Noncompliant, this form is not safe
form.uploadDir = ""; // because upload dir is not defined (by default os temp dir: /var/tmp or /tmp)
form.keepExtensions = true; // and file extensions are kept
Disabling content security policy frame-ancestors directive is security-sensitive
Clickjacking attacks occur when an attacker try to trick an user to click on certain buttons/links of a legit website. This attack can take place with malicious HTML frames well hidden in an attacker website.
https://sonarsource.github.io/rspec/#/rspec/S5732/javascript
const express = require('express');
const helmet = require('helmet');
let app = express();
app.use(
helmet.contentSecurityPolicy({
directives: {
// other directives
frameAncestors: ["'example.com'"] // Compliant
}
})
);
π Examples of incorrect code
const express = require('express');
const helmet = require('helmet');
let app = express();
app.use(
helmet.contentSecurityPolicy({
directives: {
// other directives
frameAncestors: ["'none'"] // Sensitive: frameAncestors is set to none
}
})
);
Using weak hashing algorithms is security-sensitive
https://sonarsource.github.io/rspec/#/rspec/S4790/javascript
const crypto = require("crypto");
const hash = crypto.createHash('sha512'); // Compliant
π Examples of incorrect code
const crypto = require("crypto");
const hash = crypto.createHash('sha1'); // Sensitive
Hidden files are created automatically by many tools to save user-preferences, well-known examples are .profile, .bashrc, .bash_history or .git. To simplify the view these files are not displayed by default using operating system commands like ls.
https://sonarsource.github.io/rspec/#/rspec/S5691/javascript
π Examples of correct code
let serveStatic = require("serve-static");
let app = express();
// Compliant: ignore or deny are recommended values
let serveStaticMiddleware = serveStatic('public', { 'index': false, 'dotfiles': 'ignore'});
// Compliant: by default, "dotfiles" (file or directory that begins with a dot) are not served
// (with the exception that files within a directory that begins with a dot are not ignored),
// see serve-static module documentation
let serveStaticDefault = serveStatic('public', { 'index': false});
app.use(serveStaticMiddleware);
π Examples of incorrect code
let serveStatic = require("serve-static");
let app = express();
let serveStaticMiddleware = serveStatic('public', { 'index': false, 'dotfiles': 'allow'}); // Sensitive
app.use(serveStaticMiddleware);
Deleting dynamically computed keys can be dangerous and in some cases not well optimized. Using the delete operator on keys that aren't runtime constants could be a sign that you're using the wrong data structures. Using Objects with added and removed keys can cause occasional edge case bugs, such as if a key is named "hasOwnProperty".
π Examples of correct code
const container: { [i: string]: number } = {
/* ... */
};
// Constant runtime lookups by string index
delete container.aaa;
// Constants that must be accessed by []
delete container[7];
delete container['-Infinity'];
const name = 'aaa';
switch (name) {
case "aaa":
delete container.aaa
break;
case "bbb":
delete container.bbb
break;
default:
throw new Error("Not Authorized");
break;
}
π Examples of incorrect code
// Can be replaced with the constant equivalents, such as container.aaa
delete container['aaa'];
delete container['Infinity'];
// Dynamic, difficult-to-reason-about lookups
const name = 'name';
delete container[name];
delete container[name.toUpperCase()];
Having a permissive Cross-Origin Resource Sharing policy is security-sensitive
https://sonarsource.github.io/rspec/#/rspec/S5122/javascript
π Examples of correct code
const http = require('http');
const srv = http.createServer((req, res) => {
res.writeHead(200, { 'Access-Control-Allow-Origin': 'trustedwebsite.com' }); // Compliant
res.end('ok');
});
srv.listen(3000);
const cors = require('cors');
let corsOptions = {
origin: 'trustedwebsite.com' // Compliant
};
let app = express();
app.use(cors(corsOptions));
function (req, res) {
const origin = req.header('Origin');
if (trustedOrigins.indexOf(origin) >= 0) {
res.setHeader('Access-Control-Allow-Origin', origin);
}
};
π Examples of incorrect code
function (req, res) {
const origin = req.header('Origin');
res.setHeader('Access-Control-Allow-Origin', origin); // Sensitive
};
const cors = require('cors');
let app1 = express();
app1.use(cors()); // Sensitive: by default origin is set to *
let corsOptions = {
origin: '*' // Sensitive
};
let app2 = express();
app2.use(cors(corsOptions));
const http = require('http');
const srv = http.createServer((req, res) => {
res.writeHead(200, { 'Access-Control-Allow-Origin': '*' }); // Sensitive
res.end('ok');
});
srv.listen(3000);
Force CSRF protections is security-sensitive
https://sonarsource.github.io/rspec/#/rspec/S4502/javascript
π Examples of correct code
let csrf = require('csurf');
let express = require('express');
let csrfProtection = csrf({ cookie: true });
let app = express();
app.post('/money_transfer', parseForm, csrfProtection, function (req, res) { // Compliant
res.send('Money transferred')
});
let csrf = require('csurf');
let express = require('express');
app.use(csrf({ cookie: true, ignoreMethods: ["GET"] })); // Compliant
π Examples of incorrect code
let csrf = require('csurf');
let express = require('express');
let csrfProtection = csrf({ cookie: true });
let app = express();
// Sensitive: this operation doesn't look like protected by CSURF middleware (csrfProtection is not used)
app.post('/money_transfer', parseForm, function (req, res) {
res.send('Money transferred');
});
// or
let csrf = require('csurf');
let express = require('express');
app.use(csrf({ cookie: true, ignoreMethods: ["POST", "GET"] })); // Sensitive as POST is unsafe method
Aws General Security
https://sonarsource.github.io/rspec/#/rspec/S6333/javascript https://sonarsource.github.io/rspec/#/rspec/S6329/javascript https://sonarsource.github.io/rspec/#/rspec/S6275/javascript https://sonarsource.github.io/rspec/#/rspec/S6332/javascript https://sonarsource.github.io/rspec/#/rspec/S6302/javascript https://sonarsource.github.io/rspec/#/rspec/S6304/javascript https://sonarsource.github.io/rspec/#/rspec/S6317/javascript https://sonarsource.github.io/rspec/#/rspec/S6270/javascript https://sonarsource.github.io/rspec/#/rspec/S6308/javascript https://sonarsource.github.io/rspec/#/rspec/S6303/javascript https://sonarsource.github.io/rspec/#/rspec/S6321/javascript https://sonarsource.github.io/rspec/#/rspec/S6265/javascript https://sonarsource.github.io/rspec/#/rspec/S6249/javascript https://sonarsource.github.io/rspec/#/rspec/S6281/javascript https://sonarsource.github.io/rspec/#/rspec/S6245/javascript https://sonarsource.github.io/rspec/#/rspec/S6252/javascript https://sonarsource.github.io/rspec/#/rspec/S6319/javascript https://sonarsource.github.io/rspec/#/rspec/S6327/javascript https://sonarsource.github.io/rspec/#/rspec/S6308/javascript
π Examples of correct code
import {aws_apigateway as apigateway} from "aws-cdk-lib"
const resource = api.root.addResource("example",{
defaultMethodOptions:{
authorizationType: apigateway.AuthorizationType.IAM
}
})
resource.addMethod(
"POST",
new apigateway.HttpIntegration("https://example.org"),
{
authorizationType: apigateway.AuthorizationType.IAM
}
)
resource.addMethod( // authorizationType is inherited from the Resource's configured defaultMethodOptions
"GET"
)
// or
import {aws_apigatewayv2 as apigateway} from "aws-cdk-lib"
new apigateway.CfnRoute(this, "auth", {
apiId: api.ref,
routeKey: "POST /auth",
authorizationType: "AWS_IAM",
target: exampleIntegration
})
// or
import { aws_opensearchservice as opensearchservice } from 'aws-cdk-lib';
const exampleDomain = new opensearchservice.Domain(this, 'ExampleDomain', {
version: EngineVersion.OPENSEARCH_1_3,
encryptionAtRest: {
enabled: true,
},
});
// or
import { Topic } from 'aws-cdk-lib/aws-sns';
const encryptionKey = new Key(this, 'exampleKey', {
enableKeyRotation: true,
});
new Topic(this, 'exampleTopic', {
masterKey: encryptionKey
});
// or
import { CfnNotebookInstance } from 'aws-cdk-lib/aws-sagemaker';
const encryptionKey = new Key(this, 'example', {
enableKeyRotation: true,
});
new CfnNotebookInstance(this, 'example', {
instanceType: 'instanceType',
roleArn: 'roleArn',
kmsKeyId: encryptionKey.keyId
});
// or
const s3 = require('aws-cdk-lib/aws-s3');
new s3.Bucket(this, 'id', {
bucketName: 'bucket',
versioned: true
});
// or
new s3.Bucket(this, 'id', {
encryption: s3.BucketEncryption.KMS_MANAGED,
encryptionKey: access_key
});
// or
const s3 = require('aws-cdk-lib/aws-s3');
const bucket = new s3.Bucket(this, 'example', {
bucketName: 'example',
versioned: true,
publicReadAccess: false,
enforceSSL: true
});
π Examples of incorrect code
import {aws_apigateway as apigateway} from "aws-cdk-lib"
const resource = api.root.addResource("example")
resource.addMethod(
"GET",
new apigateway.HttpIntegration("https://example.org"),
{
authorizationType: apigateway.AuthorizationType.NONE // Sensitive
}
)
// or
import {aws_apigatewayv2 as apigateway} from "aws-cdk-lib"
new apigateway.CfnRoute(this, "no-auth", {
apiId: api.ref,
routeKey: "GET /no-auth",
authorizationType: "NONE", // Sensitive
target: exampleIntegration
})
// or
import { aws_opensearchservice as opensearchservice } from 'aws-cdk-lib';
const exampleCfnDomain = new opensearchservice.CfnDomain(this, 'ExampleCfnDomain', {
engineVersion: 'OpenSearch_1.3',
}); // Sensitive, encryption must be explicitly enabled
// or
import { Topic, CfnTopic } from 'aws-cdk-lib/aws-sns';
new CfnTopic(this, 'exampleCfnTopic'); // Sensitive
// or
import { CfnNotebookInstance } from 'aws-cdk-lib/aws-sagemaker';
new CfnNotebookInstance(this, 'example', {
instanceType: 'instanceType',
roleArn: 'roleArn'
}); // Sensitive
// or
const s3 = require('aws-cdk-lib/aws-s3');
new s3.Bucket(this, 'id', {
bucketName: 'bucket',
versioned: false // Sensitive
});
// or
const s3 = require('aws-cdk-lib/aws-s3');
new s3.Bucket(this, 'id', {
bucketName: 'default'
}); // Sensitive
When a cookie is protected with the secure attribute set to true it will not be send by the browser over an unencrypted HTTP request and thus cannot be observed by an unauthorized person during a man-in-the-middle attack.
https://sonarsource.github.io/rspec/#/rspec/S2092/javascript
π Examples of correct code
let session = cookieSession({
secure: true,// Compliant
}); // Compliant
// or
const express = require('express');
const session = require('express-session');
let app = express();
app.use(session({
cookie:
{
secure: true // Compliant
}
}));
// or
let cookies = new Cookies(req, res, { keys: keys });
cookies.set('LastVisit', new Date().toISOString(), {
secure: true // Compliant
}); // Compliant
// or
const cookieParser = require('cookie-parser');
const csrf = require('csurf');
const express = require('express');
let csrfProtection = csrf({ cookie: { secure: true }}); // Compliant
π Examples of incorrect code
let session = cookieSession({
secure: false,// Sensitive
}); // Sensitive
// or
const express = require('express');
const session = require('express-session');
let app = express();
app.use(session({
cookie:
{
secure: false // Sensitive
}
}));
// or
let cookies = new Cookies(req, res, { keys: keys });
cookies.set('LastVisit', new Date().toISOString(), {
secure: false // Sensitive
}); // Sensitive
// or
const cookieParser = require('cookie-parser');
const csrf = require('csurf');
const express = require('express');
let csrfProtection = csrf({ cookie: { secure: false }}); // Sensitive
Creating cookies without the "secure" flag is security-sensitive
https://sonarsource.github.io/rspec/#/rspec/S2092/javascript
π Examples of correct code
let session = cookieSession({
secure: true,// Compliant
}); // Compliant
// Or
const express = require('express');
const session = require('express-session');
let app = express();
app.use(session({
cookie:
{
secure: true // Compliant
}
}));
// or
let cookies = new Cookies(req, res, { keys: keys });
cookies.set('LastVisit', new Date().toISOString(), {
secure: true // Compliant
}); // Compliant
// or
const cookieParser = require('cookie-parser');
const csrf = require('csurf');
const express = require('express');
let csrfProtection = csrf({ cookie: { secure: true }}); // Compliant
π Examples of incorrect code
const cookieParser = require('cookie-parser');
const csrf = require('csurf');
const express = require('express');
let csrfProtection = csrf({ cookie: { secure: false }}); // Sensitive
// or
let cookies = new Cookies(req, res, { keys: keys });
cookies.set('LastVisit', new Date().toISOString(), {
secure: false // Sensitive
}); // Sensitive
// or
const express = require('express');
const session = require('express-session');
let app = express();
app.use(session({
cookie:
{
secure: false // Sensitive
}
}));
// or
let session = cookieSession({
secure: false,// Sensitive
}); // Sensitive
Using clear-text protocols is security-sensitive
https://sonarsource.github.io/rspec/#/rspec/S5332/javascript
π Examples of correct code
url = "https://example.com"; // use enviroment or config class
url = "sftp://anonymous@example.com"; // use enviroment or config class
url = "ssh://anonymous@example.com"; // use enviroment or config class
// or
const nodemailer = require("nodemailer");
let transporter = nodemailer.createTransport({
secure: true,
requireTLS: true,
port: 465,
secured: true
});
// or
var Client = require('ftp');
var c = new Client();
c.connect({
'secure': true
});
π Examples of incorrect code
url = "http://example.com"; // Sensitive
url = "ftp://anonymous@example.com"; // Sensitive
url = "telnet://anonymous@example.com"; // Sensitive
const nodemailer = require("nodemailer");
let transporter = nodemailer.createTransport({
secure: false, // Sensitive
requireTLS: false // Sensitive
});
var Client = require('ftp');
var c = new Client();
c.connect({
'secure': false // Sensitive
});
const Telnet = require('telnet-client'); // Sensitive
If a JSON Web Token (JWT) is not signed with a strong cipher algorithm (or not signed at all) an attacker can forge it and impersonate user identities.
https://sonarsource.github.io/rspec/#/rspec/S5659/javascript
π Examples of correct code
const jwt = require('jsonwebtoken');
let token = jwt.sign({ foo: 'bar' }, key, { algorithm: 'HS256' }); // Compliant
jwt.verify(token, key, { expiresIn: 360000 * 5, algorithms: ['HS256'] }, callbackcheck); // Compliant
π Examples of incorrect code
const jwt = require('jsonwebtoken');
// Noncompliant: 'none' cipher doesn't sign the JWT (no signature will be included)
let token = jwt.sign({ foo: 'bar' }, key, { algorithm: 'none' });
// Noncompliant: 'none' cipher should not be used when verifying JWT signature
jwt.verify(token, key, { expiresIn: 360000 * 5, algorithms: ['RS256', 'none'] }, callbackcheck);
Hard-coded credentials are security-sensitive
https://sonarsource.github.io/rspec/#/rspec/S2068/javascript
π Examples of correct code
var mysql = require('mysql');
var connection = mysql.createConnection({
host: process.env.MYSQL_URL,
user: process.env.MYSQL_USERNAME,
password: process.env.MYSQL_PASSWORD,
database: process.env.MYSQL_DATABASE
});
connection.connect();
π Examples of incorrect code
var mysql = require('mysql');
var connection = mysql.createConnection(
{
host:'localhost',
user: "admin",
database: "project",
password: "mypassword", // sensitive
multipleStatements: true
});
Using hardcoded IP addresses is security-sensitive
https://sonarsource.github.io/rspec/#/rspec/S1313/javascript
π Examples of correct code
ip = process.env.IP_ADDRESS; // Compliant
const net = require('net');
var client = new net.Socket();
client.connect(80, ip, function() {
// ...
});
π Examples of incorrect code
ip = "192.168.12.42"; // Sensitive
const net = require('net');
var client = new net.Socket();
client.connect(80, ip, function() {
// ...
});
Searching OS commands in PATH is security-Sensitive
https://sonarsource.github.io/rspec/#/rspec/S4036/javascript
π Examples of correct code
const cp = require('child_process');
cp.exec('/usr/bin/file.exe'); // Compliant
π Examples of incorrect code
const cp = require('child_process');
cp.exec('file.exe'); // Sensitive
Expanding archive files without controlling resource consumption is security-sensitive
https://sonarsource.github.io/rspec/#/rspec/S5042/javascript
π Examples of correct code
const tar = require('tar');
const MAX_FILES = 10000;
const MAX_SIZE = 1000000000; // 1 GB
let fileCount = 0;
let totalSize = 0;
tar.x({
file: 'foo.tar.gz',
filter: (path, entry) => {
fileCount++;
if (fileCount > MAX_FILES) {
throw 'Reached max. number of files';
}
totalSize += entry.size;
if (totalSize > MAX_SIZE) {
throw 'Reached max. size';
}
return true;
}
});
// or
const AdmZip = require('adm-zip');
const MAX_FILES = 10000;
const MAX_SIZE = 1000000000; // 1 GB
const THRESHOLD_RATIO = 10;
let fileCount = 0;
let totalSize = 0;
let zip = new AdmZip("./foo.zip");
let zipEntries = zip.getEntries();
zipEntries.forEach(function(zipEntry) {
fileCount++;
if (fileCount > MAX_FILES) {
throw 'Reached max. number of files';
}
let entrySize = zipEntry.getData().length;
totalSize += entrySize;
if (totalSize > MAX_SIZE) {
throw 'Reached max. size';
}
let compressionRatio = entrySize / zipEntry.header.compressedSize;
if (compressionRatio > THRESHOLD_RATIO) {
throw 'Reached max. compression ratio';
}
if (!zipEntry.isDirectory) {
zip.extractEntryTo(zipEntry.entryName, ".");
}
});
// or
const fs = require("fs");
const pathmodule = require("path");
const JSZip = require("jszip");
const MAX_FILES = 10000;
const MAX_SIZE = 1000000000; // 1 GB
let fileCount = 0;
let totalSize = 0;
let targetDirectory = __dirname + '/archive_tmp';
fs.readFile("foo.zip", function(err, data) {
if (err) throw err;
JSZip.loadAsync(data).then(function (zip) {
zip.forEach(function (relativePath, zipEntry) {
fileCount++;
if (fileCount > MAX_FILES) {
throw 'Reached max. number of files';
}
// Prevent ZipSlip path traversal (S6096)
const resolvedPath = pathmodule.join(targetDirectory, zipEntry.name);
if (!resolvedPath.startsWith(targetDirectory)) {
throw 'Path traversal detected';
}
if (!zip.file(zipEntry.name)) {
fs.mkdirSync(resolvedPath);
} else {
zip.file(zipEntry.name).async('nodebuffer').then(function (content) {
totalSize += content.length;
if (totalSize > MAX_SIZE) {
throw 'Reached max. size';
}
fs.writeFileSync(resolvedPath, content);
});
}
});
});
});
// or
const yauzl = require('yauzl');
const MAX_FILES = 10000;
const MAX_SIZE = 1000000000; // 1 GB
const THRESHOLD_RATIO = 10;
yauzl.open('foo.zip', function (err, zipfile) {
if (err) throw err;
let fileCount = 0;
let totalSize = 0;
zipfile.on("entry", function(entry) {
fileCount++;
if (fileCount > MAX_FILES) {
throw 'Reached max. number of files';
}
// The uncompressedSize comes from the zip headers, so it might not be trustworthy.
// Alternatively, calculate the size from the readStream.
let entrySize = entry.uncompressedSize;
totalSize += entrySize;
if (totalSize > MAX_SIZE) {
throw 'Reached max. size';
}
if (entry.compressedSize > 0) {
let compressionRatio = entrySize / entry.compressedSize;
if (compressionRatio > THRESHOLD_RATIO) {
throw 'Reached max. compression ratio';
}
}
zipfile.openReadStream(entry, function(err, readStream) {
if (err) throw err;
// TODO: extract
});
});
});
// or
const extract = require('extract-zip')
const MAX_FILES = 10000;
const MAX_SIZE = 1000000000; // 1 GB
const THRESHOLD_RATIO = 10;
async function main() {
let fileCount = 0;
let totalSize = 0;
let target = __dirname + '/foo';
await extract('foo.zip', {
dir: target,
onEntry: function(entry, zipfile) {
fileCount++;
if (fileCount > MAX_FILES) {
throw 'Reached max. number of files';
}
// The uncompressedSize comes from the zip headers, so it might not be trustworthy.
// Alternatively, calculate the size from the readStream.
let entrySize = entry.uncompressedSize;
totalSize += entrySize;
if (totalSize > MAX_SIZE) {
throw 'Reached max. size';
}
if (entry.compressedSize > 0) {
let compressionRatio = entrySize / entry.compressedSize;
if (compressionRatio > THRESHOLD_RATIO) {
throw 'Reached max. compression ratio';
}
}
}
});
}
main();
π Examples of incorrect code
const tar = require('tar');
tar.x({ // Sensitive
file: 'foo.tar.gz'
});
// or
const AdmZip = require('adm-zip');
let zip = new AdmZip("./foo.zip");
zip.extractAllTo("."); // Sensitive
// or
const fs = require("fs");
const JSZip = require("jszip");
fs.readFile("foo.zip", function(err, data) {
if (err) throw err;
JSZip.loadAsync(data).then(function (zip) { // Sensitive
zip.forEach(function (relativePath, zipEntry) {
if (!zip.file(zipEntry.name)) {
fs.mkdirSync(zipEntry.name);
} else {
zip.file(zipEntry.name).async('nodebuffer').then(function (content) {
fs.writeFileSync(zipEntry.name, content);
});
}
});
});
});
// or
const yauzl = require('yauzl');
yauzl.open('foo.zip', function (err, zipfile) {
if (err) throw err;
zipfile.on("entry", function(entry) {
zipfile.openReadStream(entry, function(err, readStream) {
if (err) throw err;
// TODO: extract
});
});
});
// or
const extract = require('extract-zip')
async function main() {
let target = __dirname + '/test';
await extract('test.zip', { dir: target }); // Sensitive
}
main();
Using sockets is security-sensitive. It has led in the past to the following vulnerabilities:
https://sonarsource.github.io/rspec/#/rspec/S4818/javascript
π Examples of correct code
π Examples of incorrect code
const net = require('net');
var socket = new net.Socket(); // Sensitive
socket.connect(80, 'google.com');
// net.createConnection creates a new net.Socket, initiates connection with socket.connect(),
// then returns the net.Socket that starts the connection
net.createConnection({ port: port }, () => {}); // Sensitive
// net.connect is an alias to net.createConnection
net.connect({ port: port }, () => {}); // Sensitive
MIME confusion attacks occur when an attacker successfully tricks a web-browser to interpret a resource as a different type than the one expected. To correctly interpret a resource (script, image, stylesheet ...) web browsers look for the Content-Type header defined in the HTTP response received from the server, but often this header is not set or is set with an incorrect value. To avoid content-type mismatch and to provide the best user experience, web browsers try to deduce the right content-type, generally by inspecting the content of the resources (the first bytes). This "guess mechanism" is called MIME type sniffing.
https://sonarsource.github.io/rspec/#/rspec/S5734/javascript
π Examples of correct code
const express = require('express');
const helmet= require('helmet');
let app = express();
app.use(helmet.noSniff());
π Examples of incorrect code
const express = require('express');
const helmet = require('helmet');
let app = express();
app.use(
helmet({
noSniff: false, // Sensitive
})
);
The certificate chain validation includes these steps: The certificate is issued by its parent Certificate Authority or the root CA trusted by the system. Each CA is allowed to issue certificates. Each certificate in the chain is not expired.
https://sonarsource.github.io/rspec/#/rspec/S4830/javascript
π Examples of correct code
let options = {
hostname: "www.example.com",
port: 443,
path: "/",
method: "GET",
secureProtocol: "TLSv1_2_method",
};
let req = https.request(options, (res) => {
res.on('data', (d) => {
process.stdout.write(d);
});
}); // Compliant: by default rejectUnauthorized is set to true
// or
let options = {
secureProtocol: 'TLSv1_2_method'
};
let socket = tls.connect(443, "www.example.com", options, () => {
process.stdin.pipe(socket);
process.stdin.resume();
}); // Compliant: by default rejectUnauthorized is set to true
// or
let socket = request.get({
url: 'https://www.example.com/',
secureProtocol: 'TLSv1_2_method' // Compliant
}); // Compliant: by default rejectUnauthorized is set to true
π Examples of incorrect code
let options = {
hostname: 'www.example.com',
port: 443,
path: '/',
method: 'GET',
secureProtocol: 'TLSv1_2_method',
rejectUnauthorized: false ; // Noncompliant
};
let req = https.request(options, (res) => {
res.on('data', (d) => {
process.stdout.write(d);
});
}); // Noncompliant
// or
let options = {
secureProtocol: 'TLSv1_2_method',
rejectUnauthorized: false ; // Noncompliant
};
let socket = tls.connect(443, "www.example.com", options, () => {
process.stdin.pipe(socket);
process.stdin.resume();
}); // Noncompliant
// or
let socket = request.get({
url: 'www.example.com',
secureProtocol: 'TLSv1_2_method',
rejectUnauthorized: false ; // Noncompliant
});
Formatted SQL queries can be difficult to maintain, debug and can increase the risk of SQL injection when concatenating untrusted values into the query. However, this rule doesnβt detect SQL injections
https://sonarsource.github.io/rspec/#/rspec/S2077/javascript
π Examples of correct code
// === MySQL ===
const mysql = require('mysql');
const mycon = mysql.createConnection({ host: host, user: user, password: pass, database: db });
mycon.connect(function(err) {
mycon.query('SELECT name FROM users WHERE id = ?', [userinput], (err, res) => {});
});
// === PostgreSQL ===
const pg = require('pg');
const pgcon = new pg.Client({ host: host, user: user, password: pass, database: db });
pgcon.connect();
pgcon.query('SELECT name FROM users WHERE id = $1', [userinput], (err, res) => {});
π Examples of incorrect code
// === MySQL ===
const mysql = require('mysql');
const mycon = mysql.createConnection({ host: host, user: user, password: pass, database: db });
mycon.connect(function(err) {
mycon.query('SELECT * FROM users WHERE id = ' + userinput, (err, res) => {}); // Sensitive
});
// === PostgreSQL ===
const pg = require('pg');
const pgcon = new pg.Client({ host: host, user: user, password: pass, database: db });
pgcon.connect();
pgcon.query('SELECT * FROM users WHERE id = ' + userinput, (err, res) => {}); // Sensitive
Enforce a specific parameter name in catch clauses
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/catch-error-name.md
π Examples of correct code
try {} catch (exception) {}
promise.catch(exception => {});
promise.catch(error => {});
promise.catch(error1 => {});
promise.catch(error2 => {});
π Examples of incorrect code
try {} catch (badName) {}
// `_` is not allowed if it's used
try {} catch (_) {
console.log(_);
}
promise.catch(badName => {});
promise.then(undefined, badName => {});
Enforces the use of already destructured objects and their variables over accessing each property individually. Previous destructurings are easily missed which leads to an inconsistent code style.
π Examples of correct code
const {a} = foo;
console.log(a);
console.log(foo.a, foo.b);
const {a} = foo;
console.log(a, foo.b());
const {a} = foo.bar;
console.log(foo.bar);
π Examples of incorrect code
const {a} = foo;
console.log(a, foo.b);
const {a} = foo;
console.log(foo.a);
const {
a: {
b
}
} = foo;
console.log(foo.a.c);
const {bar} = foo;
const {a} = foo.bar;
A function definition should be placed as close to the top-level scope as possible without breaking its captured values. This improves readability, directly improves performance and allows JavaScript engines to better optimize performance.
π Examples of correct code
function doBar(bar) {
return bar === 'bar';
}
export function doFoo(foo) {
return doBar;
}
export function doFoo(foo) {
function doBar(bar) {
return bar === 'bar' && foo.doBar(bar);
}
return doBar;
}
π Examples of incorrect code
export function doFoo(foo) {
// Does not capture anything from the scope, can be moved to the outer scope
function doBar(bar) {
return bar === 'bar';
}
return doBar;
}
function doFoo(foo) {
const doBar = bar => {
return bar === 'bar';
};
}
This rule enforces a message value to be passed in when creating an instance of a built-in Error object, which leads to more readable and debuggable code.
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/error-message.md
π Examples of correct code
throw new TypeError('Array expected.');
const error = new AggregateError(errors, 'Promises rejected.');
π Examples of incorrect code
throw Error();
throw Error('');
throw new TypeError();
const error = new AggregateError(errors);
Enforces defining escape sequence values with uppercase characters rather than lowercase ones. This promotes readability by making the escaped value more distinguishable from the identifier.
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/escape-case.md
π Examples of correct code
const foo = '\xA9';
const foo = '\uD834';
const foo = '\u{1D306}';
const foo = '\cA';
π Examples of incorrect code
const foo = '\xa9';
const foo = '\ud834';
const foo = '\u{1d306}';
const foo = '\ca';
Enforce the use of new for all builtin's, except String, Number, Boolean, Symbol and BigInt
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/new-for-builtins.md
π Examples of correct code
const list = new Array(10);
const now = new Date();
const map = new Map([
['foo', 'bar']
]);
π Examples of incorrect code
const list = Array(10);
const now = Date();
const map = Map([
['foo', 'bar']
]);
This rule makes you specify the rules you want to disable when using eslint-disable, eslint-disable-line or eslint-disable-next-line comments.
π Examples of correct code
/* eslint-disable no-console */
console.log(message);
console.log(message); // eslint-disable-line no-console
// eslint-disable-next-line no-console
console.log(message);
π Examples of incorrect code
/* eslint-disable */
console.log(message);
console.log(message); // eslint-disable-line
// eslint-disable-next-line
console.log(message);
Prefer forβ¦of over the forEach method Do not use a for loop that can be replaced with a for-of loop
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-array-for-each.md https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-for-loop.md
π Examples of correct code
for (const element of array) {
bar(element);
}
for (const [index, element] of array.entries()) {
bar(element, index);
}
for (const [index, element] of array.entries()) {
bar(element, index, array);
}
π Examples of incorrect code
array.forEach(element => {
bar(element);
});
array?.forEach(element => {
bar(element);
});
array.forEach((element, index) => {
bar(element, index);
});
array.forEach((element, index, array) => {
bar(element, index, array);
});
for (let index = 0; index < array.length; index++) {
const element = array[index];
console.log(index, element);
}
Enforce combining multiple Array#push() into one call
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-array-push-push.md
π Examples of correct code
foo.push(1, 2, 3);
// or
const length = foo.push(1);
foo.push(2);
// or
foo.push(1);
bar();
foo.push(2);
π Examples of incorrect code
foo.push(1);
foo.push(2, 3);
Disallow member access from await expression
π Examples of correct code
const {default: foo} = await import('./foo.js');
const [, secondElement] = await getArray();
const {property} = await getObject();
const response = await fetch('/foo');
const data = await response.json();
π Examples of incorrect code
const foo = (await import('./foo.js')).default;
const secondElement = (await getArray())[1];
const property = (await getObject()).property;
const data = await (await fetch('/foo')).json();
Do not use document.cookie directly It's not recommended to use document.cookie directly as it's easy to get the string wrong. Instead, you should use the Cookie Store API or a cookie library.
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-document-cookie.md
π Examples of correct code
await cookieStore.set({
name: 'foo',
value: 'bar',
expires: Date.now() + 24 * 60 * 60 * 1000,
domain: 'example.com'
});
const array = document.cookie.split('; ');
import Cookies from 'js-cookie';
Cookies.set('foo', 'bar');
π Examples of incorrect code
document.cookie =
'foo=bar' +
'; Path=/' +
'; Domain=example.com' +
'; expires=Fri, 31 Dec 9999 23:59:59 GMT' +
'; Secure';
document.cookie += '; foo=bar';
Disallow any files only containing the following: Whitespace Comments Directives Empty statements Empty block statements Hashbang
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-empty-file.md
π Examples of correct code
await cookieStore.set({
name: 'foo',
value: 'bar',
expires: Date.now() + 24 * 60 * 60 * 1000,
domain: 'example.com'
});
const array = document.cookie.split('; ');
import Cookies from 'js-cookie';
Cookies.set('foo', 'bar');
π Examples of incorrect code
const x = 0;
/* Comment */
;
Require Array.isArray() instead of instanceof Array
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-instanceof-array.md
π Examples of correct code
Array.isArray(array);
Array.isArray([ 1, 2, 3 ]);
π Examples of incorrect code
array instanceof Array;
[ 1, 2, 3 ] instanceof Array;
The removeEventListener function must be called with a reference to the same function that was passed to addEventListener. Calling removeEventListener with an inline function or the result of an inline .bind() call is indicative of an error, and won't actually remove the listener.
π Examples of correct code
window.removeEventListener('click', listener);
window.removeEventListener('click', getListener());
class MyElement extends HTMLElement {
constructor() {
super();
this.handler = this.handler.bind(this);
}
handler() {}
disconnectedCallback() {
this.removeEventListener('click', this.handler);
}
}
π Examples of incorrect code
window.removeEventListener('click', fn.bind(window));
window.removeEventListener('click', () => {});
window.removeEventListener('click', function () {});
class MyElement extends HTMLElement {
handler() {}
disconnectedCallback() {
this.removeEventListener('click', this.handler.bind(this));
}
}
This rule adds onto the built-in no-lonely-if rule, which only disallows if statements in else, not in if.
https://eslint.org/docs/latest/rules/no-lonely-if https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-lonely-if.md
π Examples of correct code
if (foo && bar) {
// β¦
}
if (foo) {
// β¦
} else if (bar && baz) {
// β¦
}
if (foo) {
// β¦
} else if (bar) {
if (baz) {
// β¦
}
} else {
// β¦
}
π Examples of incorrect code
if (foo) {
if (bar) {
// β¦
}
}
if (foo) {
// β¦
} else if (bar) {
if (baz) {
// β¦
}
}
Improved version of the no-nested-ternary ESLint rule, which allows cases where the nested ternary is only one level and wrapped in Parentheses.
https://eslint.org/docs/latest/rules/no-nested-ternary https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-nested-ternary.md
π Examples of correct code
const foo = i > 5 ? (i < 100 ? true : false) : true;
const foo = i > 5 ? (i < 100 ? true : false) : (i < 100 ? true : false);
π Examples of incorrect code
const foo = i > 5 ? i < 100 ? true : false : true;
const foo = i > 5 ? true : (i < 100 ? true : (i < 1000 ? true : false));
Enforce the use of Buffer.from() and Buffer.alloc() instead of the deprecated new Buffer()
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-new-buffer.md
π Examples of correct code
const buffer = Buffer.from('7468697320697320612074c3a97374', 'hex');
const buffer = Buffer.from([0x62, 0x75, 0x66, 0x66, 0x65, 0x72])
const buffer = Buffer.alloc(10);
π Examples of incorrect code
const buffer = new Buffer('7468697320697320612074c3a97374', 'hex');
const buffer = new Buffer([0x62, 0x75, 0x66, 0x66, 0x65, 0x72]);
const buffer = new Buffer(10);
this should be used directly. If you want a reference to this from a higher scope, consider using arrow function expression or Function#bind().
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-this-assignment.md
π Examples of correct code
setTimeout(() => {
this.bar();
}, 1000);
setTimeout(function () {
this.bar();
}.bind(this), 1000);
class Bar {
constructor(fooInstance) {
this.fooInstance = fooInstance;
}
method() {
this.fooInstance.baz();
}
}
new Bar(this).method();
π Examples of incorrect code
const foo = this;
setTimeout(function () {
foo.bar();
}, 1000);
const foo = this;
class Bar {
method() {
foo.baz();
}
}
new Bar().method();
Disallow useless fallback when spreading in object literals
π Examples of correct code
const object = {...foo};
const object = {...(foo && {})};
const array = [...(foo || [])];
π Examples of incorrect code
const object = {...(foo || {})};
const object = {...(foo ?? {})};
Disallow useless array length check
Array#some() returns false for an empty array. There is no need to check if the array is not empty. Array#every() returns true for an empty array. There is no need to check if the array is empty.
We only check .length === 0, .length !== 0, and .length > 0.
π Examples of correct code
if (array.every(Boolean));
if (array.some(Boolean));
const isAllTrulyOrEmpty = array.every(Boolean);
if (array.length === 0 || anotherCheck() || array.every(Boolean));
const isNonEmptyAllTrulyArray = array.length > 0 && array.every(Boolean);
const isEmptyArrayOrAllTruly = array.length === 0 || array.some(Boolean);
π Examples of incorrect code
if (array.length === 0 || array.every(Boolean));
if (array.length !== 0 && array.some(Boolean));
if (array.length > 0 && array.some(Boolean));
const isAllTrulyOrEmpty = array.length === 0 || array.every(Boolean);
Disallow unnecessary spread
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-useless-spread.md
π Examples of correct code
const array = [firstElement, secondElement, thirdElement];
const object = {firstProperty, secondProperty, thirdProperty};
foo(firstArgument, secondArgument, thirdArgument);
const object = new Foo(firstArgument, secondArgument, thirdArgument);
const array = [...foo, bar];
const object = {...foo, bar};
foo(foo, ...bar);
const object = new Foo(...foo, bar);
const set = new Set(iterable);
const results = await Promise.all(iterable);
for (const foo of set);
function * foo() {
yield * anotherGenerator();
}
π Examples of incorrect code
const array = [firstElement, ...[secondElement], thirdElement];
const object = {firstProperty, ...{secondProperty}, thirdProperty};
foo(firstArgument, ...[secondArgument], thirdArgument);
const object = new Foo(firstArgument, ...[secondArgument], thirdArgument);
const set = new Set([...iterable]);
const results = await Promise.all([...iterable]);
for (const foo of [...set]);
function * foo() {
yield * [...anotherGenerator()];
}
Disallow useless case in switch statements
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-useless-switch-case.md
π Examples of correct code
switch (foo) {
case 1:
case 2:
handleCase1And2();
break;
}
switch (foo) {
case 1:
handleCase1();
break;
default:
handleDefaultCase();
break;
}
switch (foo) {
case 1:
handleCase1();
// Fallthrough
default:
handleDefaultCase();
break;
}
switch (foo) {
// This is actually useless, but we only check cases where the last case is the `default` case
case 1:
default:
handleDefaultCase();
break;
case 2:
handleCase2();
break;
}
π Examples of incorrect code
switch (foo) {
case 1:
default:
handleDefaultCase();
break;
}
Disallow useless undefined
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-useless-undefined.md
π Examples of correct code
let foo;
const {foo} = bar;
const noop = () => {};
function foo() {
return;
}
function* foo() {
yield;
}
function foo(bar) {
}
function foo({bar}) {
}
foo();
π Examples of incorrect code
let foo = undefined;
const {foo = undefined} = bar;
const noop = () => undefined;
function foo() {
return undefined;
}
function* foo() {
yield undefined;
}
function foo(bar = undefined) {
}
function foo({bar = undefined}) {
}
foo(undefined);
Prefer .addEventListener() and .removeEventListener() over on-functions
π Examples of correct code
foo.addEventListener('click', () => {});
foo.addEventListener('keydown', () => {});
foo.bar.addEventListener('click', onClick);
foo.removeEventListener('click', onClick);
π Examples of incorrect code
foo.onclick = () => {};
foo.onkeydown = () => {};
foo.bar.onclick = onClick;
foo.onclick = null;
Prefer .find(β¦) over the first element from .filter(β¦)
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-array-find.md
π Examples of correct code
const item = array.find(x => callback(x));
item = array.find(x => callback(x));
π Examples of incorrect code
const item = array.filter(x => callback(x))[0];
const item = array.filter(x => callback(x)).shift();
const [item] = array.filter(x => callback(x));
[item] = array.filter(x => callback(x));
Prefer Array#indexOf() over Array#findIndex() when looking for the index of an item
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-array-index-of.md
π Examples of correct code
const index = foo.indexOf('foo');
const index = foo.findIndex(x => x == undefined);
const index = foo.findIndex(x => x !== 'foo');
const index = foo.findIndex((x, index) => x === index);
const index = foo.findIndex(x => (x === 'foo') && isValid());
const index = foo.findIndex(x => y === 'foo');
const index = foo.findIndex(x => y.x === 'foo');
const index = foo.findIndex(x => {
const bar = getBar();
return x === bar;
});
π Examples of incorrect code
const index = foo.findIndex(x => x === 'foo');
const index = foo.findIndex(x => 'foo' === x);
const index = foo.findIndex(x => {
return x === 'foo';
});
Prefer .some(β¦) over .filter(β¦).length check and .find(β¦)
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-array-some.md
π Examples of correct code
const hasUnicorn = array.some(element => callback(element));
if (array.some(element => callback(element))) {
// β¦
}
const foo = array.find(element => callback(element)) || bar;
<template>
<div v-if="array.some(element => callback(element))">Vue</div>
</template>
π Examples of incorrect code
const hasUnicorn = array.filter(element => callback(element)).length > 0;
const hasUnicorn = array.filter(element => callback(element)).length !== 0;
const hasUnicorn = array.filter(element => callback(element)).length >= 1;
if (array.find(element => callback(element))) {
// β¦
}
const foo = array.find(element => callback(element)) ? bar : baz;
const hasUnicorn = array.find(element => callback(element) !== undefined);
const hasUnicorn = array.find(element => callback(element) != null);
<template>
<div v-if="array.find(element => callback(element))">Vue</div>
</template>
<template>
<div v-if="array.filter(element => callback(element)).length > 0">Vue</div>
</template>
Prefer Node#append() over Node#appendChild()
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-dom-node-append.md
π Examples of correct code
foo.append(bar);
foo.append('bar');
foo.append(bar, 'baz');
π Examples of incorrect code
foo.appendChild(bar);
Prefer childNode.remove()
over parentNode.removeChild(childNode)
π Examples of correct code
foo.remove();
this.remove();
π Examples of incorrect code
parentNode.removeChild(foo);
parentNode.removeChild(this);
Prefer .includes()
over .indexOf()
and Array#some() when checking for existence or non-existence
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-includes.md https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/prefer-includes.md
π Examples of correct code
const str = 'foobar';
str.indexOf('foo') !== -n;
str.indexOf('foo') !== 1;
!str.indexOf('foo') === 1;
!str.indexOf('foo') === -n;
str.includes('foo');
[1,2,3].includes(4);
const isFound = foo.includes('foo');
const isFound = foo.some(x => x == undefined);
const isFound = foo.some(x => x !== 'foo');
const isFound = foo.some((x, index) => x === index);
const isFound = foo.some(x => (x === 'foo') && isValid());
const isFound = foo.some(x => y === 'foo');
const isFound = foo.some(x => y.x === 'foo');
const isFound = foo.some(x => {
const bar = getBar();
return x === bar;
});
π Examples of incorrect code
[].indexOf('foo') !== -1;
x.indexOf('foo') != -1;
str.indexOf('foo') > -1;
'foobar'.indexOf('foo') >= 0;
x.indexOf('foo') === -1
const isFound = foo.some(x => x === 'foo');
const isFound = foo.some(x => 'foo' === x);
const isFound = foo.some(x => {
return x === 'foo';
});
Enforces the use of KeyboardEvent#key over KeyboardEvent#keyCode which is deprecated. The .key property is also more semantic and readable.
π Examples of correct code
window.addEventListener("click", event => {
console.log(event.key);
});
window.addEventListener("keydown", event => {
if (event.key === "Backspace") {
console.log("Backspace was pressed");
}
});
π Examples of incorrect code
window.addEventListener("keydown", event => {
console.log(event.keyCode);
});
window.addEventListener("keydown", event => {
if (event.keyCode === 8) {
console.log("Backspace was pressed");
}
});
Prefer negative index over .length - index for {String,Array,TypedArray}#slice(), Array#splice() and Array#at()
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-negative-index.md
π Examples of correct code
foo.slice(-2, -1);
foo.splice(-1, 1);
foo.at(-1);
Array.prototype.slice.call(foo, -2, -1);
Array.prototype.slice.apply(foo, [-2, -1]);
π Examples of incorrect code
foo.slice(foo.length - 2, foo.length - 1);
foo.splice(foo.length - 1, 1);
foo.at(foo.length - 1);
Array.prototype.slice.call(foo, foo.length - 2, foo.length - 1);
Array.prototype.slice.apply(foo, [foo.length - 2, foo.length - 1]);
Prefer omitting the catch binding parameter
π Examples of correct code
try {} catch {}
try {} catch (error) {
console.error(error);
}
π Examples of incorrect code
try {} catch (notUsedError) {}
try {} catch ({message}) {}
Prefer borrowing methods from the prototype instead of the instance When βborrowingβ a method from Array or Object, it's clearer to get it from the prototype than from an instance.
π Examples of correct code
const array = Array.prototype.slice.apply(bar);
const hasProperty = Object.prototype.hasOwnProperty.call(foo, 'property');
Reflect.apply(Array.prototype.forEach, arrayLike, [callback]);
const maxValue = Math.max.apply(Math, numbers);
π Examples of incorrect code
const array = [].slice.apply(bar);
const hasProperty = {}.hasOwnProperty.call(foo, 'property');
Reflect.apply([].forEach, arrayLike, [callback]);
Prefer .querySelector() over .getElementById(), .querySelectorAll() over .getElementsByClassName() and .getElementsByTagName()
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-query-selector.md
π Examples of correct code
document.querySelector('#foo');
document.querySelector('.bar');
document.querySelector('main #foo .bar');
document.querySelectorAll('.foo .bar');
document.querySelectorAll('li a');
document.querySelector('li').querySelectorAll('a');
π Examples of incorrect code
document.getElementById('foo');
document.getElementsByClassName('foo bar');
document.getElementsByTagName('main');
document.getElementsByClassName(fn());
Prefer RegExp#test()
over String#match()
and RegExp#exec()
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-regexp-test.md
π Examples of correct code
if (/unicorn/.test(string)) {}
<template>
<div v-if="/unicorn/.test(string)">Vue</div>
</template>
π Examples of incorrect code
if (string.match(/unicorn/)) {}
if (/unicorn/.exec(string)) {}
<template>
<div v-if="/unicorn/.exec(string)">Vue</div>
</template>
Prefer the spread operator over Array.from(β¦), Array#concat(β¦), Array#slice() and String#split('')
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-spread.md
π Examples of correct code
[ ...set ].map(element => foo(element));
const array = [ ...array1, ...array2 ];
const tail = array.slice(1);
const copy = [ ...array ];
π Examples of incorrect code
Array.from(set).map(element => foo(element));
const array = array1.concat(array2);
const copy = array.slice();
const characters = string.split('');
Prefer String#replaceAll() over regex searches with the global flag The String#replaceAll() method is both faster and safer as you don't have to escape the regex if the string is not a literal.
π Examples of correct code
string.replace(/Non-literal characters .*/g, "");
string.replace(/Extra flags/gi, "");
string.replace("Not a regex expression", "")
string.replaceAll("Literal characters only", "");
π Examples of incorrect code
string.replace(/This has no special regex symbols/g, "");
string.replace(/\(It also checks for escaped regex symbols\)/g, "");
string.replace(/Works for u flag too/gu, "");
Prefer String#startsWith() & String#endsWith() over RegExp#test()
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-string-starts-ends-with.md https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/prefer-string-starts-ends-with.md
π Examples of correct code
const foo = baz.startsWith("bar");
const foo = baz.endsWith("bar");
const foo = baz?.startsWith("bar");
const foo = (baz ?? "").startsWith("bar");
const foo = String(baz).startsWith("bar");
const foo = /^bar/i.test(baz);
π Examples of incorrect code
const foo = /^bar/.test(baz);
const foo = /bar$/.test(baz);
// or
declare const foo: string;
// starts with
foo[0] === 'b';
foo.charAt(0) === 'b';
foo.indexOf('bar') === 0;
foo.slice(0, 3) === 'bar';
foo.substring(0, 3) === 'bar';
foo.match(/^bar/) != null;
/^bar/.test(foo);
// ends with
foo[foo.length - 1] === 'b';
foo.charAt(foo.length - 1) === 'b';
foo.lastIndexOf('bar') === foo.length - 3;
foo.slice(-3) === 'bar';
foo.substring(foo.length - 3) === 'bar';
foo.match(/bar$/) != null;
/bar$/.test(foo);
Prefer String#trimStart()
/ String#trimEnd()
over String#trimLeft()
/ String#trimRight()
π Examples of correct code
const foo = bar.trimStart();
const foo = bar.trimEnd();
π Examples of incorrect code
const foo = bar.trimLeft();
const foo = bar.trimRight();
Prefer switch over multiple else-if
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-switch.md
π Examples of correct code
if (foo === 1) {
// 1
} else if (foo === 2) {
// 2
}
switch (foo) {
case 1: {
// 1
break;
}
case 2: {
// 2
break;
}
case 3: {
// 3
break;
}
default: {
// default
}
}
π Examples of incorrect code
if (foo === 1) {
// 1
} else if (foo === 2) {
// 2
} else if (foo === 3) {
// 3
} else {
// default
}
This rule enforces the use of ternary expressions over 'simple' if-else statements, where 'simple' means the consequent and alternate are each one line and have the same basic type and form.
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-ternary.md
π Examples of correct code
function func() {
return test ? a : b;
}
function* func() {
yield (test ? a : b);
}
async function func() {
await (test ? a() : b());
}
const error = test ? new Error('foo') : new Error('bar');
throw error;
let foo;
foo = test ? 1 : 2;
// Multiple expressions
let foo;
let bar;
if (test) {
foo = 1;
bar = 2;
} else{
foo = 2;
}
// Different expressions
function func() {
if (test) {
return a;
} else {
throw new Error('error');
}
}
// Assign to different variable
let foo;
let bar;
if (test) {
foo = 1;
} else{
baz = 2;
}
π Examples of incorrect code
function func() {
if (test) {
return a;
} else {
return b;
}
}
function* func() {
if (test) {
yield a;
} else {
yield b;
}
}
async function func() {
if (test) {
await a();
} else {
await b();
}
}
if (test) {
throw new Error('foo');
} else {
throw new Error('bar');
}
let foo;
if (test) {
foo = 1;
} else {
foo = 2;
}
Enforces newlines between the operands of a ternary expression if the expression spans multiple lines.
https://eslint.org/docs/latest/rules/multiline-ternary
π Examples of correct code
foo > bar ? value1 : value2;
foo > bar ?
value1 :
value2;
foo > bar ?
(baz > qux ? value1 : value2) :
value3;
foo > bar ?
(baz > qux ?
value1 :
value2) :
value3;
foo > bar &&
bar > baz ?
value1 :
value2;
π Examples of incorrect code
foo > bar ? value1 :
value2;
foo > bar ?
value1 : value2;
foo > bar &&
bar > baz ? value1 : value2;
Using complete words results in more readable code. Not everyone knows all your abbreviations. Code is written only once, but read many times.
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prevent-abbreviations.md
π Examples of correct code
const error = new Error();
const event = document.createEvent('Event');
const levels = {
error: 0
};
this.event = 'click';
class Button {}
// Property is not checked by default
const levels = {
err: 0
};
// Property is not checked by default
this.evt = 'click';
π Examples of incorrect code
const e = new Error();
const e = document.createEvent('Event');
class Btn {}
Enforce consistent relative URL style
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/relative-url-style.md
π Examples of correct code
const url = new URL('foo', base);
π Examples of incorrect code
const url = new URL('./foo', base)
Enforce using the separator argument with Array#join() It's better to make it clear what the separator is when calling Array#join(), instead of relying on the default comma (',') separator.
π Examples of correct code
const string = array.join(',');
const string = array.join('|');
const string = Array.prototype.join.call(arrayLike, '');
const string = [].join.call(arrayLike, '\n');
π Examples of incorrect code
const string = array.join();
const string = Array.prototype.join.call(arrayLike);
const string = [].join.call(arrayLike);
Enforce using the digits argument with Number#toFixed()
It's better to make it clear what the value of the digits argument is when calling Number#toFixed(), instead of relying on the default value of 0.
π Examples of correct code
const string = foo.toFixed(0);
const string = foo.toFixed(2);
const integer = Math.floor(foo);
const integer = Math.ceil(foo);
const integer = Math.round(foo);
const integer = Math.trunc(foo);
π Examples of incorrect code
const string = number.toFixed();
Fix whitespace-insensitive template indentation
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/template-indent.md
π Examples of correct code
function foo() {
const sqlQuery = sql`
select *
from students
where first_name = ${x}
and last_name = ${y}
`;
const gqlQuery = gql`
query user(id: 5) {
firstName
lastName
}
`;
const html = /* HTML */ `
<div>
<span>hello</span>
</div>
`;
}
π Examples of incorrect code
function foo() {
const sqlQuery = sql`
select *
from students
where first_name = ${x}
and last_name = ${y}
`;
const gqlQuery = gql`
query user(id: 5) {
firstName
lastName
}
`;
const html = /* HTML */ `
<div>
<span>hello</span>
</div>
`;
}
Function overload signatures represent multiple ways a function can be called, potentially with different return types. It's typical for an interface or type alias describing a function to place all overload signatures next to each other. If Signatures placed elsewhere in the type are easier to be missed by future developers reading the code.
π Examples of correct code
declare namespace Foo {
export function foo(s: string): void;
export function foo(n: number): void;
export function foo(sn: string | number): void;
export function bar(): void;
}
type Foo = {
foo(s: string): void;
foo(n: number): void;
foo(sn: string | number): void;
bar(): void;
};
interface Foo {
foo(s: string): void;
foo(n: number): void;
foo(sn: string | number): void;
bar(): void;
}
class Foo {
foo(s: string): void;
foo(n: number): void;
foo(sn: string | number): void {}
bar(): void {}
}
export function bar(): void;
export function foo(s: string): void;
export function foo(n: number): void;
export function foo(sn: string | number): void;
π Examples of incorrect code
declare namespace Foo {
export function foo(s: string): void;
export function foo(n: number): void;
export function bar(): void;
export function foo(sn: string | number): void;
}
type Foo = {
foo(s: string): void;
foo(n: number): void;
bar(): void;
foo(sn: string | number): void;
};
interface Foo {
foo(s: string): void;
foo(n: number): void;
bar(): void;
foo(sn: string | number): void;
}
class Foo {
foo(s: string): void;
foo(n: number): void;
bar(): void {}
foo(sn: string | number): void {}
}
export function foo(s: string): void;
export function foo(n: number): void;
export function bar(): void;
export function foo(sn: string | number): void;
TypeScript provides several directive comments that can be used to alter how it processes files. Using these to suppress TypeScript compiler errors reduces the effectiveness of TypeScript overall. Instead, it's generally better to correct the types of code, to make directives unnecessary.
π Examples of correct code
if (false) {
// Compiler warns about unreachable code error
console.log('hello');
}
if (false) {
// @ts-expect-error: Unreachable code error
console.log('hello');
}
if (false) {
/*
@ts-expect-error: Unreachable code error
*/
console.log('hello');
}
π Examples of incorrect code
if (false) {
// @ts-ignore: Unreachable code error
console.log('hello');
}
if (false) {
/*
@ts-ignore: Unreachable code error
*/
console.log('hello');
}
Useful when migrating from TSLint to ESLint. Once TSLint has been removed, this rule helps locate TSLint annotations (e.g. // tslint:disable).
π Examples of correct code
// This is a comment that just happens to mention tslint
/* This is a multiline comment that just happens to mention tslint */
someCode(); // This is a comment that just happens to mention tslint
π Examples of incorrect code
/* tslint:disable */
/* tslint:enable */
/* tslint:disable:rule1 rule2 rule3... */
/* tslint:enable:rule1 rule2 rule3... */
// tslint:disable-next-line
someCode(); // tslint:disable-line
// tslint:disable-next-line:rule1 rule2 rule3...
This style checks for any getter methods that return literal values, and requires them to be defined using fields with the readonly modifier instead.
π Examples of correct code
class Mx {
public readonly myField1 = 1;
// not a literal
public readonly myField2 = [1, 2, 3];
private readonly ['myField3'] = 'hello world';
public get myField4() {
return `hello from ${window.location.href}`;
}
}
π Examples of incorrect code
class Mx {
public static get myField1() {
return 1;
}
private get ['myField2']() {
return 'hello world';
}
}
When constructing a generic class, you can specify the type arguments on either the left-hand side (as a type annotation) or the right-hand side (as part of the constructor call):
π Examples of correct code
const map = new Map<string, number>();
const map: Map<string, number> = new MyMap();
const set = new Set<string>();
const set = new Set();
const set: Set<string> = new Set<string>();
π Examples of incorrect code
const map: Map<string, number> = new Map();
const set: Set<string> = new Set();
TypeScript supports defining arbitrary object keys using an index signature. TypeScript also has a builtin type named Record to create an empty object defining only an index signature. For example, the following types are equal:
π Examples of correct code
type Foo = Record<string, unknown>;
π Examples of incorrect code
interface Foo {
[key: string]: unknown;
}
type Foo = {
[key: string]: unknown;
};
This rule aims to standardize the use of type assertion style across the codebase. Keeping to one syntax consistently helps with code readability.
π Examples of correct code
const x: T = { ... };
const y = { ... } as any;
const z = { ... } as unknown;
foo({ ... } as T);
new Clazz({ ... } as T);
function foo() { throw { bar: 5 } as Foo }
const foo = <Foo props={{ ... } as Bar}/>;
π Examples of incorrect code
const x = { ... } as T;
function foo() {
return { ... } as T;
}
TypeScript provides two common ways to define an object type: interface and type.
π Examples of correct code
type T = string;
type Foo = string | {};
interface T {
x: number;
}
π Examples of incorrect code
type T = { x: number };
TypeScript allows specifying a keyword on exports to indicate that the export exists only in the type system, not at runtime. This allows transpilers to drop exports without knowing the types of the dependencies.type
π Examples of correct code
const x = 1;
type T = number;
export { x, type T };
π Examples of incorrect code
const x = 1;
type T = number;
export { x, T };
TypeScript allows specifying a type keyword on imports to indicate that the export exists only in the type system, not at runtime. This allows transpilers to drop imports without knowing the types of the dependencies.
π Examples of correct code
import { type Foo } from 'Foo';
import type Bar from 'Bar';
type T = Foo;
const x: Bar = 1;
π Examples of incorrect code
import type { Foo } from 'Foo';
// or
import { Foo } from 'Foo';
import Bar from 'Bar';
type T = Foo;
const x: Bar = 1;
TypeScript allows three delimiters between members in interfaces and type aliases:
π Examples of correct code
interface Foo {
name: string;
greet(): string;
}
interface Foo { name: string }
type Bar = {
name: string;
greet(): string;
}
type Bar = { name: string }
type FooBar = { name: string; greet(): string }
π Examples of incorrect code
// missing semicolon delimiter
interface Foo {
name: string
greet(): string
}
// using incorrect delimiter
interface Bar {
name: string,
greet(): string,
}
// missing last member delimiter
interface Baz {
name: string;
greet(): string
}
// incorrect delimiter
type FooBar = { name: string, greet(): string }
// last member should not have delimiter
type FooBar = { name: string; greet(): string; }
This rule aims to standardize the way classes, interfaces, and type literals are structured and ordered.
π Examples of correct code
[
// Index signature
"signature",
// Fields
"public-static-field",
"protected-static-field",
"private-static-field",
"#private-static-field",
"public-decorated-field",
"protected-decorated-field",
"private-decorated-field",
"public-instance-field",
"protected-instance-field",
"private-instance-field",
"#private-instance-field",
"public-abstract-field",
"protected-abstract-field",
"public-field",
"protected-field",
"private-field",
"#private-field",
"static-field",
"instance-field",
"abstract-field",
"decorated-field",
"field",
// Static initialization
"static-initialization",
// Constructors
"public-constructor",
"protected-constructor",
"private-constructor",
// Getters
"public-static-get",
"protected-static-get",
"private-static-get",
"#private-static-get",
"public-decorated-get",
"protected-decorated-get",
"private-decorated-get",
"public-instance-get",
"protected-instance-get",
"private-instance-get",
"#private-instance-get",
"public-abstract-get",
"protected-abstract-get",
"public-get",
"protected-get",
"private-get",
"#private-get",
"static-get",
"instance-get",
"abstract-get",
"decorated-get",
"get",
// Setters
"public-static-set",
"protected-static-set",
"private-static-set",
"#private-static-set",
"public-decorated-set",
"protected-decorated-set",
"private-decorated-set",
"public-instance-set",
"protected-instance-set",
"private-instance-set",
"#private-instance-set",
"public-abstract-set",
"protected-abstract-set",
"public-set",
"protected-set",
"private-set",
"static-set",
"instance-set",
"abstract-set",
"decorated-set",
"set",
// Methods
"public-static-method",
"protected-static-method",
"private-static-method",
"#private-static-method",
"public-decorated-method",
"protected-decorated-method",
"private-decorated-method",
"public-instance-method",
"protected-instance-method",
"private-instance-method",
"#private-instance-method",
"public-abstract-method",
"protected-abstract-method"
]
π Examples of incorrect code
// another order
Using a non-null assertion (!) next to an assign or equals check (= or == or ===) creates code that is confusing as it looks similar to a not equals check (!= !==).
π Examples of correct code
interface Foo {
bar?: string;
num?: number;
}
const foo: Foo = getFoo();
const isEqualsBar = foo.bar === "hello";
const isEqualsNum = 1 + foo.num! === 2;
π Examples of incorrect code
interface Foo {
bar?: string;
num?: number;
}
const foo: Foo = getFoo();
const isEqualsBar = foo.bar! == 'hello';
const isEqualsNum = 1 + foo.num! == 2;
The ! non-null assertion operator in TypeScript is used to assert that a value's type does not include null or undefined.
π Examples of correct code
const foo: { bar: number } | null = null;
const bar = foo!.bar;
function foo(bar: number | undefined) {
const bar: number = bar!;
}
function foo(bar?: { n: number }) {
return bar?.n;
}
π Examples of incorrect code
const foo: { bar: number } | null = null;
const bar = foo!!!.bar;
function foo(bar: number | undefined) {
const bar: number = bar!!!;
}
function foo(bar?: { n: number }) {
return bar!?.n;
}
A for-in loop (for (var i in o)) iterates over the properties of an Object. While it is legal to use for-in loops with array types, it is not common. for-in will iterate over the indices of the array as strings, omitting any "holes" in the array.
π Examples of correct code
for (const value of array) {
console.log(value);
}
for (const [ index, value ] of array.entries()) {
console.log(index, value);
}
π Examples of incorrect code
for (const i in array) {
console.log(array[i]);
}
for (const i in array) {
console.log(i, array[i]);
}
TypeScript is able to infer the types of parameters, properties, and variables from their default or initial values. There is no need to use an explicit : type annotation on one of those constructs initialized to a boolean, number, or string.
π Examples of correct code
const a = 10n;
const a = BigInt(10);
const a = !0;
const a = Boolean(null);
const a = true;
const a = null;
const a = 10;
const a = Infinity;
const a = NaN;
const a = Number('1');
const a = /a/;
const a = new RegExp('a');
const a = `str`;
const a = String(1);
const a = Symbol('a');
const a = undefined;
const a = void someValue;
π Examples of incorrect code
const a: bigint = 10n;
const a: bigint = BigInt(10);
const a: boolean = !0;
const a: boolean = Boolean(null);
const a: boolean = true;
const a: null = null;
const a: number = 10;
const a: number = Infinity;
const a: number = NaN;
const a: number = Number('1');
const a: RegExp = /a/;
const a: RegExp = new RegExp('a');
const a: string = `str`;
const a: string = String(1);
const a: symbol = Symbol('a');
const a: undefined = undefined;
const a: undefined = void someValue;
Assigning a variable to this instead of properly using arrow lambdas may be a symptom of pre-ES6 practices or not managing scope well.
π Examples of correct code
setTimeout(() => {
this.doWork();
});
π Examples of incorrect code
const self = this;
setTimeout(function () {
self.doWork();
});
!: Non-null assertion as: Traditional type assertion with a coincidentally equivalent type
π Examples of correct code
const maybe = Math.random() > 0.5 ? '' : undefined;
const definitely = maybe!;
const alsoDefinitely = maybe!;
π Examples of incorrect code
const maybe = Math.random() > 0.5 ? '' : undefined;
const definitely = maybe as string;
const alsoDefinitely = <string>maybe;
The constructor parameter is assigned to the class property at the beginning of the constructor
π Examples of correct code
class Foo {
constructor(readonly name: string) {}
}
class Foo {
constructor(private name: string) {}
}
class Foo {
constructor(protected name: string) {}
}
class Foo {
constructor(public name: string) {}
}
class Foo {
constructor(private readonly name: string) {}
}
class Foo {
constructor(protected readonly name: string) {}
}
class Foo {
constructor(public readonly name: string) {}
}
π Examples of incorrect code
class Foo {
constructor(name: string) {
this.name = name;
}
}
TypeScript enums are a practical way to organize semantically related constant values. Members of enums thatdon't have explicit values are by default given sequentially increasing numbers.
π Examples of correct code
enum Status {
Open = 'Open',
Close = 'Close',
}
enum Direction {
Up = 1,
Down = 2,
}
enum Color {
Red = 'Red',
Green = 'Green',
Blue = 'Blue',
}
π Examples of incorrect code
enum Status {
Open = 1,
Close,
}
enum Direction {
Up,
Down,
}
enum Color {
Red,
Green = 'Green'
Blue = 'Blue',
}
TypeScript allows for two common ways to declare a type for a function:
Function type: () => string Object type with a signature: { (): string }
π Examples of correct code
type Example = () => string;
function foo(example: () => number): number {
return bar();
}
// returns the function itself, not the `this` argument.
type ReturnsSelf = (arg: string) => ReturnsSelf;
function foo(bar: { (): string; baz: number }): string {
return bar();
}
interface Foo {
bar: string;
}
interface Bar extends Foo {
(): void;
}
// multiple call signatures (overloads) is allowed:
interface Overloaded {
(data: string): number;
(id: number): string;
}
// this is equivelent to Overloaded interface.
type Intersection = ((data: string) => number) & ((id: number) => string);
π Examples of incorrect code
interface Example {
(): string;
}
function foo(example: { (): number }): number {
return example();
}
interface ReturnsSelf {
// returns the function itself, not the `this` argument.
(arg: string): this;
}
TypeScript historically allowed a form of code organization called "custom modules" (module Example {}), later renamed to "namespaces" (namespace Example).
π Examples of correct code
namespace Example {}
declare module 'foo' {}
π Examples of incorrect code
module Example {}
The ?? nullish coalescing runtime operator allows providing a default value when dealing with null or undefined. Because the nullish coalescing operator only coalesces when the original value is null or undefined, it is much safer than relying upon logical OR operator chaining ||, which coalesces on any falsy value.
This rule reports when an || operator can be safely replaced with a ??.
π Examples of correct code
const foo: any = 'bar';
foo ?? 'a string';
foo ?? 'a string';
foo ?? 'a string';
foo ?? 'a string';
const foo: string | undefined = 'bar';
foo ?? 'a string';
foo ?? 'a string';
const foo: string | null = 'bar';
foo ?? 'a string';
foo ?? 'a string';
π Examples of incorrect code
const foo: any = 'bar';
foo !== undefined && foo !== null ? foo : 'a string';
foo === undefined || foo === null ? 'a string' : foo;
foo == undefined ? 'a string' : foo;
foo == null ? 'a string' : foo;
const foo: string | undefined = 'bar';
foo !== undefined ? foo : 'a string';
foo === undefined ? 'a string' : foo;
const foo: string | null = 'bar';
foo !== null ? foo : 'a string';
foo === null ? 'a string' : foo;
This rule reports on code where an && operator can be safely replaced with ?. optional chaining.
π Examples of correct code
foo?.a?.b?.c;
foo?.['a']?.b?.c;
foo?.a?.b?.method?.();
foo?.a?.b?.c?.d?.e;
!foo?.bar;
!foo?.[bar];
!foo?.bar?.baz?.();
π Examples of incorrect code
foo && foo.a && foo.a.b && foo.a.b.c;
foo && foo['a'] && foo['a'].b && foo['a'].b.c;
foo && foo.a && foo.a.b && foo.a.b.method && foo.a.b.method();
// With empty objects
(((foo || {}).a || {}).b || {}).c;
(((foo || {})['a'] || {}).b || {}).c;
// With negated `or`s
!foo || !foo.bar;
!foo || !foo[bar];
!foo || !foo.bar || !foo.bar.baz || !foo.bar.baz();
// this rule also supports converting chained strict nullish checks:
foo &&
foo.a != null &&
foo.a.b !== null &&
foo.a.b.c != undefined &&
foo.a.b.c.d !== undefined &&
foo.a.b.c.d.e;
This rule reports on private members are marked as readonly if they're never modified outside of the constructor.
π Examples of correct code
class Container {
// Public members might be modified externally
public publicMember: boolean;
// Protected members might be modified by child classes
protected protectedMember: number;
// This is modified later on by the class
private modifiedLater = 'unchanged';
private readonly myProp = 'readonly';
public mutate() {
this.modifiedLater = 'mutated';
}
}
π Examples of incorrect code
class Container {
// These member variables could be marked as readonly
private neverModifiedMember = true;
private onlyModifiedInConstructor: number;
public constructor(
onlyModifiedInConstructor: number,
// Private parameter properties can also be marked as readonly
private neverModifiedParameter: string,
) {
this.onlyModifiedInConstructor = onlyModifiedInConstructor;
}
}
It's common to call Array#reduce with a generic type, such as an array or object, as the initial value. Since these values are empty, their types are not usable:
π Examples of correct code
[1, 2, 3].reduce<number[]>((arr, num) => arr.concat(num * 2), []);
['a', 'b'].reduce<Record<string, boolean>>(
(accum, name) => ({
...accum,
[name]: true,
}),
{},
);
π Examples of incorrect code
[1, 2, 3].reduce((arr, num) => arr.concat(num * 2), [] as number[]);
['a', 'b'].reduce(
(accum, name) => ({
...accum,
[name]: true,
}),
{} as Record<string, boolean>,
);
In contrast, non-async Promise - returning functions are technically capable of either. Code that handles the results of those functions will often need to handle both cases, which can get complex. This rule's practice removes a requirement for creating code to handle both cases.
π Examples of correct code
const arrowFunctionReturnsPromise = async () => Promise.resolve('value');
async function functionReturnsPromise() {
return Promise.resolve('value');
}
π Examples of incorrect code
const arrowFunctionReturnsPromise = () => Promise.resolve('value');
function functionReturnsPromise() {
return Promise.resolve('value');
}
When called without a compare function, Array#sort() converts all non-undefined array elements into strings and then compares said strings based off their UTF-16
π Examples of correct code
const array: any[];
const userDefinedType: { sort(): void };
array.sort((a, b) => a - b);
array.sort((a, b) => a.localeCompare(b));
userDefinedType.sort();
const one = '1';
const two = '2';
const three = '3';
[one, two, three].sort();
π Examples of incorrect code
const array: any[];
const stringArray: string[];
array.sort();
// String arrays should be sorted using `String#localeCompare`.
stringArray.sort();
Sorting union (|) and intersection (&) types can help:
keep your codebase standardized find repeated types reduce diff churn This rule reports on any types that aren't sorted alphabetically.
π Examples of correct code
type T1 = A | B;
type T2 = { a: string } & { b: string };
type T3 = [1, 2, 3] & [1, 2, 4];
type T4 =
| any
| string
| A
| B
| number[]
| string[]
| readonly number[]
| readonly string[]
| 'a'
| 'b'
| 'a'
| 'b'
| (() => string)
| (() => void)
| { a: string }
| { b: string }
| [1, 2, 3]
| [1, 2, 4];
π Examples of incorrect code
type T1 = B | A;
type T2 = { b: string } & { a: string };
type T3 = [1, 2, 4] & [1, 2, 3];
type T4 =
| [1, 2, 4]
| [1, 2, 3]
| { b: string }
| { a: string }
| (() => void)
| (() => string)
| 'b'
| 'a'
| 'b'
| 'a'
| readonly string[]
| readonly number[]
| string[]
| number[]
| B
| A
| string
| any;
Consistency is an important part of any style guide. While it is a personal preference where to put the opening brace of blocks, it should be consistent across a whole project. Having an inconsistent style distracts the reader from seeing the important parts of the code.
π Examples of correct code
if (a) {
b();
}
if (a) {
b();
} else{ /*no error. this is checked by `keyword-spacing` rule.*/
c();
}
class C {
static{} /*no error. this is checked by `keyword-spacing` rule.*/
}
function a() {}
for (;;) {
b();
}
try {} catch(a) {}
enum Breakpoint {
Large, Medium;
}
interface State {
currentBreakpoint: Breakpoint;
}
π Examples of incorrect code
if (a){
b();
}
function a(){}
for (;;){
b();
}
try {} catch(a){}
class Foo{
constructor(){}
}
enum Breakpoint{
Large, Medium;
}
interface State{
currentBreakpoint: Breakpoint;
}
Disallow the use of alert, confirm, and prompt
https://eslint.org/docs/latest/rules/no-alert
π Examples of correct code
// Example Switch Alerts
Swal.fire(
'Good job!',
'You clicked the button!',
'success'
)
customAlert("Something happened!");
customConfirm("Are you sure?");
customPrompt("Who are you?");
function foo() {
var alert = myCustomLib.customAlert;
alert();
}
π Examples of incorrect code
alert("here!");
confirm("Are you sure?");
prompt("What's your name?", "John Doe");
Disallow function declarations that contain unsafe references inside loop statements
https://eslint.org/docs/latest/rules/no-loop-func https://sonarsource.github.io/rspec/#/rspec/S1515/javascript
π Examples of correct code
var a = function() {};
for (var i=10; i; i--) {
a();
}
π Examples of incorrect code
for (var i=10; i; i--) {
(function() { return i; })();
}
while(i) {
var a = function() { return i; };
a();
}
do {
function a() { return i; };
a();
} while (i);
let foo = 0;
for (let i = 0; i < 10; ++i) {
//Bad, `foo` is not in the loop-block's scope and `foo` is modified in/after the loop
setTimeout(() => console.log(foo));
foo += 1;
}
for (let i = 0; i < 10; ++i) {
//Bad, `foo` is not in the loop-block's scope and `foo` is modified in/after the loop
setTimeout(() => console.log(foo));
}
foo = 100;
Verifies calls of super() in constructors.
https://eslint.org/docs/latest/rules/constructor-super
π Examples of correct code
class A {
constructor() { }
}
class A extends B {
constructor() {
super();
}
}
π Examples of incorrect code
class A {
constructor() {
super(); // This is a SyntaxError.
}
}
class A extends B {
constructor() { } // Would throw a ReferenceError.
}
// Classes which inherits from a non constructor are always problems.
class A extends null {
constructor() {
super(); // Would throw a TypeError.
}
}
class A extends null {
constructor() { } // Would throw a ReferenceError.
}
Enforces that a return statement is present in property getters.
https://eslint.org/docs/latest/rules/getter-return
π Examples of correct code
p = {
get name(){
return "nicholas";
}
};
Object.defineProperty(p, "age", {
get: function (){
return 18;
}
});
class P{
get name(){
return "nicholas";
}
}
π Examples of incorrect code
p = {
get name(){
// no returns.
}
};
Object.defineProperty(p, "age", {
get: function (){
// no returns.
}
});
class P{
get name(){
// no returns.
}
}
Disallows modifying variables of class declarations.
https://eslint.org/docs/latest/rules/no-class-assign
π Examples of correct code
let A = class {
b() {
A = 0; // A is a variable.
}
}
// OR
class A {
b(A) {
A = 0; // A is a parameter.
}
}
π Examples of incorrect code
class A { }
A = 0;
// OR
A = 0;
class A { }
// OR
class A {
b() {
A = 0;
}
}
// OR
let A = class A {
b() {
A = 0;
// `let A` is shadowed by the class name.
}
}
Disallows comparing against -0.
https://eslint.org/docs/latest/rules/no-compare-neg-zero
π Examples of correct code
if (x === 0) {
// doSomething()...
}
π Examples of incorrect code
if (x === -0) {
// doSomething()...
}
Disallow reassigning const variables
https://eslint.org/docs/latest/rules/no-const-assign
π Examples of correct code
const a = 0;
console.log(a);
// or
let a = 0;
a = 1;
// or
// `a` is re-defined (not modified) on each loop step.
for (const a in [ 1, 2, 3 ]) {
console.log(a);
}
π Examples of incorrect code
const a = 0;
a = 1;
// or
const a = 0;
a += 1;
// or
const a = 0;
++a;
Disallow duplicate class members
https://eslint.org/docs/latest/rules/no-dupe-class-members
π Examples of correct code
class Foo {
bar() { }
qux() { }
}
class Foo {
get bar() { }
set bar(value) { }
}
class Foo {
bar;
qux;
}
class Foo {
bar;
qux() { }
}
class Foo {
static bar() { }
bar() { }
}
π Examples of incorrect code
class Foo {
bar() { }
bar() { }
}
class Foo {
bar() { }
get bar() { }
}
class Foo {
bar;
bar;
}
class Foo {
bar;
bar() { }
}
class Foo {
static bar() { }
static bar() { }
}
https://eslint.org/docs/rules/no-dupe-keys#no-dupe-keys
π Examples of correct code
var foo = {
bar: "baz",
quxx: "qux"
};
π Examples of incorrect code
var foo = {
bar: "baz",
bar: "qux"
};
var foo = {
"bar": "baz",
bar: "qux"
};
var foo = {
0x1: "baz",
1: "qux"
};
Disallow duplicate arguments in function definitions
https://eslint.org/docs/latest/rules/no-dupe-args#rule-details
π Examples of correct code
function foo(a, b, c) {
console.log(a, b, c);
}
var bar = function (a, b, c) {
console.log(a, b, c);
};
π Examples of incorrect code
function foo(a, b, a) {
console.log("value of the second a:", a);
}
var bar = function (a, b, a) {
console.log("value of the second a:", a);
};
Disallow control flow statements in finally blocks
https://eslint.org/docs/latest/rules/no-unsafe-finally
π Examples of correct code
let foo = function() {
try {
return 1;
} catch(err) {
return 2;
} finally {
console.log("hola!");
}
};
let foo = function() {
try {
return 1;
} catch(err) {
return 2;
} finally {
let a = function() {
return "hola!";
}
}
};
let foo = function(a) {
try {
return 1;
} catch(err) {
return 2;
} finally {
switch(a) {
case 1: {
console.log("hola!")
break;
}
}
}
};
π Examples of incorrect code
let foo = function() {
try {
return 1;
} catch(err) {
return 2;
} finally {
return 3;
}
};
let foo = function() {
try {
return 1;
} catch(err) {
return 2;
} finally {
throw new Error;
}
};
Disallow control flow statements in finally blocks
https://eslint.org/docs/latest/rules/no-unsafe-finally
π Examples of correct code
import mod, { named } from "./mod.mjs"
import * as mod_ns from "./mod.mjs"
mod.prop = 1
named.prop = 2
mod_ns.named.prop = 3
// Known Limitation
function test(obj) {
obj.named = 4 // Not errored because 'obj' is not namespace objects.
}
test(mod_ns) // Not errored because it doesn't know that 'test' updates the member of the argument.
π Examples of incorrect code
import mod, { named } from "./mod.mjs"
import * as mod_ns from "./mod.mjs"
mod = 1 // ERROR: 'mod' is readonly.
named = 2 // ERROR: 'named' is readonly.
mod_ns.named = 3 // ERROR: The members of 'mod_ns' are readonly.
mod_ns = {} // ERROR: 'mod_ns' is readonly.
// Can't extend 'mod_ns'
Object.assign(mod_ns, { foo: "foo" }) // ERROR: The members of 'mod_ns' are readonly.
Forbid a module from importing itself.
https://github.com/import-js/eslint-plugin-import/blob/HEAD/docs/rules/no-self-import.md
π Examples of correct code
// foo.js
import bar from './bar';
const bar = require('./bar');
π Examples of incorrect code
// foo.js
import foo from './foo';
const foo = require('./foo');
// index.js
import index from '.';
const index = require('.');
Reports funny business with exports, like repeated exports of names or defaults.
https://github.com/import-js/eslint-plugin-import/blob/HEAD/docs/rules/export.md
π Examples of correct code
// foo.js
export default class MyClass { /*...*/ } // Multiple default exports.
function makeFunction() { return new MyClass(...arguments) }
export default makeFunction // Multiple default exports.
π Examples of incorrect code
export default class MyClass { /*...*/ } // Multiple default exports.
function makeClass() { return new MyClass(...arguments) }
export default makeClass // Multiple default exports.
// OR
export const foo = function () { /*...*/ } // Multiple exports of name 'foo'.
function bar() { /*...*/ }
export { bar as foo } // Multiple exports of name 'foo'.
No useless loop
https://eslint.org/docs/rules/no-unreachable-loop
π Examples of correct code
do {
doSomething();
} while (false)
for (let i = 0; i < 1; i++) {
doSomething(i);
}
for (const a of [1]) {
doSomething(a);
}
π Examples of incorrect code
while (foo) {
doSomething(foo);
foo = foo.parent;
break;
}
function verifyList(head) {
let item = head;
do {
if (verify(item)) {
return true;
} else {
return false;
}
} while (item);
}
function findSomething(arr) {
for (var i = 0; i < arr.length; i++) {
if (isSomething(arr[i])) {
return arr[i];
} else {
throw new Error("Doesn't exist.");
}
}
}
for (key in obj) {
if (key.startsWith("_")) {
break;
}
firstKey = key;
firstValue = obj[key];
break;
}
for (foo of bar) {
if (foo.id === id) {
doSomething(foo);
}
break;
}
Disallow literal numbers that lose precision
https://eslint.org/docs/latest/rules/no-loss-of-precision
π Examples of correct code
const x = 12345
const x = 123.456
const x = 123e34
const x = 12300000000000000000000000
const x = 0x1FFFFFFFFFFFFF
const x = 9007199254740991
const x = 9007_1992547409_91
π Examples of incorrect code
const x = 9007199254740993
const x = 5123000000000000000000000000001
const x = 1230000000000000000000000.0
const x = .1230000000000000000000000
const x = 0X20000000000001
const x = 0X2_000000000_0001;
Disallow calling a function with a value with type any
.
π Examples of correct code
declare function foo(arg1: string, arg2: number, arg3: string): void;
foo('a', 1, 'b');
const tuple1 = ['a', 1, 'b'] as const;
foo(...tuple1);
declare function bar(arg1: string, arg2: number, ...rest: string[]): void;
const array: string[] = ['a'];
bar('a', 1, ...array);
declare function baz(arg1: Set<string>, arg2: Map<string, string>): void;
foo(new Set<string>(), new Map<string, string>());
π Examples of incorrect code
declare function foo(arg1: string, arg2: number, arg3: string): void;
const anyTyped = 1 as any;
foo(...anyTyped);
foo(anyTyped, 1, 'a');
const anyArray: any[] = [];
foo(...anyArray);
const tuple1 = ['a', anyTyped, 'b'] as const;
foo(...tuple1);
const tuple2 = [1] as const;
foo('a', ...tuple, anyTyped);
declare function bar(arg1: string, arg2: number, ...rest: string[]): void;
const x = [1, 2] as [number, ...number[]];
foo('a', ...x, anyTyped);
declare function baz(arg1: Set<string>, arg2: Map<string, string>): void;
foo(new Set<any>(), new Map<any, string>());
If a default import is requested, report if there is no default export in the imported module.
https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/default.md
π Examples of correct code
// ./foo.js
export class Example {}
import foo from './foo'
// assuming 'node_modules' are ignored (true by default)
import someModule from 'some-module'
π Examples of incorrect code
import bar from './bar' // no default export found in ./bar
import baz from './baz' // no default export found in ./baz
Ensures an imported module can be resolved to a module on the local filesystem, as defined by standard Node require.resolve behavior.
https://github.com/import-js/eslint-plugin-import/blob/HEAD/docs/rules/no-unresolved.md
π Examples of correct code
import x from './bar' // file found
π Examples of incorrect code
import x from './foo' // File not found
Verifies that all named imports are part of the set of named exports in the referenced module.
https://github.com/import-js/eslint-plugin-import/blob/HEAD/docs/rules/named.md
π Examples of correct code
// ./foo.js
export const foo = "I'm so foo"
// -------------------
// ./bar.js
import { foo } from './foo';
// ES7 proposal
export { foo as bar } from './foo';
// node_modules without jsnext:main are not analyzed by default
// (import/ignore setting)
import { SomeNonsenseThatDoesntExist } from 'react';
π Examples of incorrect code
// ./baz.js
import { notFoo } from './foo';
// ES7 proposal
export { notFoo as defNotBar } from './foo';
// will follow 'jsnext:main', if available
import { dontCreateStore } from 'redux';
The types of the arguments to built-in functions are specified in the JavaScript language specifications
https://sonarsource.github.io/rspec/#/rspec/S3782/javascript
π Examples of correct code
const isTooSmall = Math.abs(x) < 0.0042;
π Examples of incorrect code
const isTooSmall = Math.abs(x < 0.0042); // Type require number no boolean
Under the strict mode, this keywords outside of classes or class-like objects might be undefined and raise a TypeError.
https://eslint.org/docs/latest/rules/no-invalid-this#rule-details https://typescript-eslint.io/rules/no-invalid-this
π Examples of correct code
"use strict";
this.a = 0;
baz(() => this);
function Foo() {
// OK, this is in a legacy style constructor.
this.a = 0;
baz(() => this);
}
class Foo {
constructor() {
// OK, this is in a constructor.
this.a = 0;
baz(() => this);
}
}
var obj = {
foo: function foo() {
// OK, this is in a method (this function is on object literal).
this.a = 0;
}
};
var obj = {
foo() {
// OK, this is in a method (this function is on object literal).
this.a = 0;
}
};
var obj = {
get foo() {
// OK, this is in a method (this function is on object literal).
return this.a;
}
};
var obj = Object.create(null, {
foo: {value: function foo() {
// OK, this is in a method (this function is on object literal).
this.a = 0;
}}
});
Object.defineProperty(obj, "foo", {
value: function foo() {
// OK, this is in a method (this function is on object literal).
this.a = 0;
}
});
Object.defineProperties(obj, {
foo: {value: function foo() {
// OK, this is in a method (this function is on object literal).
this.a = 0;
}}
});
function Foo() {
this.foo = function foo() {
// OK, this is in a method (this function assigns to a property).
this.a = 0;
baz(() => this);
};
}
obj.foo = function foo() {
// OK, this is in a method (this function assigns to a property).
this.a = 0;
};
Foo.prototype.foo = function foo() {
// OK, this is in a method (this function assigns to a property).
this.a = 0;
};
class Foo {
// OK, this is in a class field initializer.
a = this.b;
// OK, static initializers also have valid this.
static a = this.b;
foo() {
// OK, this is in a method.
this.a = 0;
baz(() => this);
}
static foo() {
// OK, this is in a method (static methods also have valid this).
this.a = 0;
baz(() => this);
}
static {
// OK, static blocks also have valid this.
this.a = 0;
baz(() => this);
}
}
var foo = (function foo() {
// OK, the `bind` method of this function is called directly.
this.a = 0;
}).bind(obj);
foo.forEach(function() {
// OK, `thisArg` of `.forEach()` is given.
this.a = 0;
baz(() => this);
}, thisArg);
/** @this Foo */
function foo() {
// OK, this function has a `@this` tag in its JSDoc comment.
this.a = 0;
}
π Examples of incorrect code
"use strict";
(function() {
this.a = 0;
baz(() => this);
})();
function foo() {
this.a = 0;
baz(() => this);
}
var foo = function() {
this.a = 0;
baz(() => this);
};
foo(function() {
this.a = 0;
baz(() => this);
});
var obj = {
aaa: function() {
return function foo() {
// There is in a method `aaa`, but `foo` is not a method.
this.a = 0;
baz(() => this);
};
}
};
foo.forEach(function() {
this.a = 0;
baz(() => this);
});
In the constructor of derived classes, if this/super are used before super() calls, it raises a reference error.
https://eslint.org/docs/latest/rules/no-this-before-super
π Examples of correct code
class A {
constructor() {
this.a = 0; // OK, this class doesn't have an `extends` clause.
}
}
class A extends B {
constructor() {
super();
this.a = 0; // OK, this is after `super()`.
}
}
class A extends B {
foo() {
this.a = 0; // OK. this is not in a constructor.
}
}
π Examples of incorrect code
class A extends B {
constructor() {
this.a = 0;
super();
}
}
class A extends B {
constructor() {
this.foo();
super();
}
}
class A extends B {
constructor() {
super.foo();
super();
}
}
class A extends B {
constructor() {
super(this.foo());
}
}
Disallow calling global object properties as functions
https://eslint.org/docs/latest/rules/no-obj-calls
π Examples of correct code
function area(r) {
return Math.PI * r * r;
}
var object = JSON.parse("{}");
var value = Reflect.get({ x: 1, y: 2 }, "x");
var first = Atomics.load(foo, 0);
var segmenterFr = new Intl.Segmenter("fr", { granularity: "word" });
π Examples of incorrect code
var math = Math();
var newMath = new Math();
var json = JSON();
var newJSON = new JSON();
var reflect = Reflect();
var newReflect = new Reflect();
var atomics = Atomics();
var newAtomics = new Atomics();
var intl = Intl();
var newIntl = new Intl();
Disallow empty destructuring patterns
https://eslint.org/docs/latest/rules/no-empty-pattern
π Examples of correct code
π Examples of incorrect code
var {} = foo;
var [] = foo;
var {a: {}} = foo;
var {a: []} = foo;
function foo({}) {}
function foo([]) {}
function foo({a: {}}) {}
function foo({a: []}) {}
Disallow unnecessary computed property keys in objects and classes
https://eslint.org/docs/latest/rules/no-useless-computed-key
π Examples of correct code
var c = { 'a': 0 };
var c = { 0: 0 };
var a = { x() {} };
var c = { a: 0 };
var c = { '0+1,234': 0 };
π Examples of incorrect code
var a = { ['0']: 0 };
var a = { ['0+1,234']: 0 };
var a = { [0]: 0 };
var a = { ['x']: 0 };
var a = { ['x']() {} };
Disallow useless code
https://eslint.org/docs/rules/no-useless-call#no-useless-call
π Examples of correct code
foo.call(obj, 1, 2, 3);
foo.apply(obj, [1, 2, 3]);
obj.foo.call(null, 1, 2, 3);
obj.foo.apply(null, [1, 2, 3]);
obj.foo.call(otherObj, 1, 2, 3);
obj.foo.apply(otherObj, [1, 2, 3]);
// The argument list is variadic.
// Those are warned by the `prefer-spread` rule.
foo.apply(undefined, args);
foo.apply(null, args);
obj.foo.apply(obj, args);
a[++i].foo.call(a[i], 1, 2, 3);
π Examples of incorrect code
foo.call(undefined, 1, 2, 3);
foo.apply(undefined, [1, 2, 3]);
foo.call(null, 1, 2, 3);
foo.apply(null, [1, 2, 3]);
// These are same as `obj.foo(1, 2, 3);`
obj.foo.call(obj, 1, 2, 3);
obj.foo.apply(obj, [1, 2, 3]);
a[i++].foo.call(a[i++], 1, 2, 3);
Disallow useless code
https://eslint.org/docs/rules/no-useless-catch#no-useless-catch
π Examples of correct code
try {
doSomethingThatMightThrow();
} catch (e) {
doSomethingBeforeRethrow();
throw e;
}
try {
doSomethingThatMightThrow();
} catch (e) {
handleError(e);
}
try {
doSomethingThatMightThrow();
} finally {
cleanUp();
}
π Examples of incorrect code
try {
doSomethingThatMightThrow();
} catch (e) {
throw e;
}
try {
doSomethingThatMightThrow();
} catch (e) {
throw e;
} finally {
cleanUp();
}
Disallow useless code
https://eslint.org/docs/rules/no-unused-expressions
π Examples of correct code
{} // In this context, this is a block statement, not an object literal
{myLabel: someVar} // In this context, this is a block statement with a label and expression, not an object literal
function namedFunctionDeclaration () {}
(function aGenuineIIFE () {}());
f()
a = 0
new C
delete a.b
void a
a ? b() : c();
a ? (b = c) : d();
π Examples of incorrect code
0
if(0) 0
{0}
f(0), {}
a && b()
a, b()
c = a, b;
a() && function namedFunctionInExpressionContext () {f();}
(function anIncompleteIIFE () {});
injectGlobal`body{ color: red; }`
function foo() {
"bar" + 1;
}
class Foo {
static {
"use strict"; // class static blocks do not have directive prologues
}
}
Disallow useless code
https://eslint.org/docs/rules/no-useless-return#no-useless-return
π Examples of correct code
function foo() { return 5; }
function foo() {
return doSomething();
}
function foo() {
if (condition) {
bar();
return;
} else {
baz();
}
qux();
}
function foo() {
switch (bar) {
case 1:
doSomething();
return;
default:
doSomethingElse();
}
}
function foo() {
for (const foo of bar) {
return;
}
}
π Examples of incorrect code
function foo() { return; }
function foo() {
doSomething();
return;
}
function foo() {
if (condition) {
bar();
return;
} else {
baz();
}
}
function foo() {
switch (bar) {
case 1:
doSomething();
default:
doSomethingElse();
return;
}
}
Disallow useless code
https://eslint.org/docs/rules/no-useless-constructor#options
π Examples of correct code
class A { }
class A {
constructor () {
doSomething();
}
}
class B extends A {
constructor() {
super('foo');
}
}
class B extends A {
constructor() {
super();
doSomething();
}
}
π Examples of incorrect code
class A {
constructor () {
}
}
class B extends A {
constructor (...args) {
super(...args);
}
}
In JavaScript, prior to ES6, variable and function declarations are hoisted to the top of a scope, so itβs possible to use identifiers before their formal declarations in code.
https://eslint.org/docs/latest/rules/no-use-before-define
π Examples of correct code
var a;
a = 10;
alert(a);
function f() {}
f(1);
var b = 1;
function g() {
return b;
}
{
let c;
c++;
}
{
class C {
static x = C;
}
}
{
const C = class C {
static x = C;
}
}
{
const C = class {
x = C;
}
}
{
const C = class C {
static {
C.x = "foo";
}
}
}
const foo = 1;
export { foo };
π Examples of incorrect code
alert(a);
var a = 10;
f();
function f() {}
function g() {
return b;
}
var b = 1;
{
alert(c);
let c = 1;
}
{
class C extends C {}
}
{
class C {
static x = "foo";
[C.x]() {}
}
}
{
const C = class {
static x = C;
}
}
{
const C = class {
static {
C.x = "foo";
}
}
}
export { foo };
const foo = 1;
JavaScript will call toString() on an object when it is converted to a string, such as when + adding to a string or in ${} template literals.
π Examples of correct code
// These types all have useful .toString()s
'Text' + true;
`Value: ${123}`;
`Arrays too: ${[1, 2, 3]}`;
(() => {}).toString();
// Defining a custom .toString class is considered acceptable
class CustomToString {
toString() {
return 'Hello, world!';
}
}
`Value: ${new CustomToString()}`;
const literalWithToString = {
toString: () => 'Hello, world!',
};
`Value: ${literalWithToString}`;
π Examples of incorrect code
// Passing an object or class instance to string concatenation:
'' + {};
class MyClass {}
const value = new MyClass();
value + '';
// Interpolation and manual .toString() calls too:
`Value: ${value}`;
({}.toString());
"in" should not be used with primitive types
https://sonarsource.github.io/rspec/#/rspec/S3785/javascript
π Examples of correct code
const x = "Foo";
if(typeof x === "string")
x.length
π Examples of incorrect code
var x = "Foo";
"length" in x; // Noncompliant: TypeError
0 in x; // Noncompliant: TypeError
Results of operations on strings should not be ignored
https://sonarsource.github.io/rspec/#/rspec/S1154/javascript
π Examples of correct code
var str = "..."
str = str.toUpperCase();
π Examples of incorrect code
var str = "..."
str.toUpperCase(); // Noncompliant
There are situations where super() must be invoked and situations where super() cannot be invoked. The basic rule is: a constructor in a non-derived class cannot invoke super(); a constructor in a derived class must invoke super().
Furthermore: super() must be invoked before the this and super keywords can be used. super() must be invoked with the same number of arguments as the base class' constructor. super() can only be invoked in a constructor - not in any other method. super() cannot be invoked multiple times in the same constructor.
https://sonarsource.github.io/rspec/#/rspec/S3854/javascript
π Examples of correct code
class Dog extends Animal {
constructor(name) {
super();
this.name = name;
super.doSomething();
}
}
π Examples of incorrect code
class Dog extends Animal {
constructor(name) {
super();
this.name = name;
super(); // Noncompliant
super.doSomething();
}
}
Types without members, 'any' and 'never' should not be used in type intersections
https://sonarsource.github.io/rspec/#/rspec/S4335/javascript
π Examples of correct code
function foo(p: MyType | null) {
// ...
}
// or
function foo(p: MyType & AnotherType) {
// ...
}
function bar(p: any) {
// ...
}
π Examples of incorrect code
function foo(p: MyType & null) { // Noncompliant
// ...
}
function bar(p: MyType & any) { // Noncompliant
// ...
}
Regular expressions with the global flag turned on can be a source of tricky bugs for uninformed users, and should therefore be used with caution. Such regular expressions are stateful, that is, they maintain an internal state through the lastIndex property, which is updated and used as starting point on every call to RegExp.prototype.test() and RegExp.prototype.exec(), even when testing a different string. The lastIndex property is eventually reset when these functions return false and null respectively.
https://sonarsource.github.io/rspec/#/rspec/S6351/javascript
π Examples of correct code
const datePattern = /\d{4}-\d{2}-\d{2}/;
datePattern.test('2020-08-06');
datePattern.test('2019-10-10'); // Compliant
const reg = /foo*/g;
const str = 'foodie fooled football';
while ((result = reg.exec(str)) !== null) { // Compliant
/* ... */
}
const stickyPattern = /abc/y; // Compliant
stickyPattern.test(/* ... */);
π Examples of incorrect code
const datePattern = /\d{4}-\d{2}-\d{2}/g;
datePattern.test('2020-08-06');
datePattern.test('2019-10-10'); // Noncompliant: the regex will return "false" despite the date being well-formed
const str = 'foodie fooled football';
// Noncompliant: a regex is defined at each iteration causing an infinite loop
while ((result = /foo*/g.exec(str)) !== null) {
/* ... */
}
const stickyPattern = /abc/gy; // Noncompliant: a regex defined as both sticky and global ignores the global flag
stickyPattern.test(/* ... */);
Enforces for loop update clause moving the counter in the right direction.
https://eslint.org/docs/latest/rules/for-direction https://sonarsource.github.io/rspec/#/rspec/S888/javascript
π Examples of correct code
for (var i = 0; i < 10; i++) {
}
π Examples of incorrect code
for (var i = 0; i < 10; i--) {
}
for (var i = 10; i >= 0; i++) {
}
for (var i = 0; i > 10; i++) {
}
Disallow unnecessary calls to .bind()
https://eslint.org/docs/latest/rules/no-extra-bind
π Examples of correct code
var x = function () {
this.foo();
}.bind(bar);
var x = function (a) {
return a + 1;
}.bind(foo, bar);
π Examples of incorrect code
var x = function () {
foo();
}.bind(bar);
var x = (() => {
foo();
}).bind(bar);
var x = (() => {
this.foo();
}).bind(bar);
var x = function () {
(function () {
this.foo();
}());
}.bind(bar);
var x = function () {
function foo() {
this.bar();
}
}.bind(baz);
Disallow template literal placeholder syntax in regular strings
https://eslint.org/docs/latest/rules/no-template-curly-in-string
π Examples of correct code
`Hello ${name}!`;
`Time: ${12 * 60 * 60 * 1000}`;
templateFunction`Hello ${name}`;
π Examples of incorrect code
"Hello ${name}!";
'Hello ${name}!';
"Time: ${12 * 60 * 60 * 1000}";
Disallow duplicate conditions in if-else-if chains
https://eslint.org/docs/latest/rules/no-dupe-else-if
π Examples of correct code
if (isSomething(x)) {
foo();
} else if (isSomethingElse(x)) {
bar();
}
if (a) {
foo();
} else if (b) {
bar();
} else if (c && d) {
baz();
} else if (c && e) {
quux();
} else {
quuux();
}
if (n === 1) {
foo();
} else if (n === 2) {
bar();
} else if (n === 3) {
baz();
} else if (n === 4) {
quux();
} else if (n === 5) {
quuux();
}
π Examples of incorrect code
if (isSomething(x)) {
foo();
} else if (isSomething(x)) {
bar();
}
if (a) {
foo();
} else if (b) {
bar();
} else if (c && d) {
baz();
} else if (c && d) {
quux();
} else {
quuux();
}
if (n === 1) {
foo();
} else if (n === 2) {
bar();
} else if (n === 3) {
baz();
} else if (n === 2) {
quux();
} else if (n === 5) {
quuux();
}
Disallow unused private class members
https://eslint.org/docs/latest/rules/no-unused-private-class-members
π Examples of correct code
class Foo {
#usedMember = 42;
method() {
return this.#usedMember;
}
}
class Foo {
#usedMethod() {
return 42;
}
anotherMethod() {
return this.#usedMethod();
}
}
class Foo {
get #usedAccessor() {}
set #usedAccessor(value) {}
method() {
this.#usedAccessor = 42;
}
}
π Examples of incorrect code
class Foo {
#unusedMember = 5;
}
class Foo {
#usedOnlyInWrite = 5;
method() {
this.#usedOnlyInWrite = 42;
}
}
class Foo {
#usedOnlyToUpdateItself = 5;
method() {
this.#usedOnlyToUpdateItself++;
}
}
class Foo {
#unusedMethod() {}
}
class Foo {
get #unusedAccessor() {}
set #unusedAccessor(value) {}
}
Disallow expressions where the operation doesn't affect the value
https://eslint.org/docs/latest/rules/no-constant-binary-expression
π Examples of correct code
const value1 = x == null;
const value2 = (condition ? x : {}) || DEFAULT;
const value3 = !(foo == null);
const value4 = Boolean(foo) === true;
const objIsEmpty = Object.keys(someObj).length === 0;
const arrIsEmpty = someArr.length === 0;
π Examples of incorrect code
const value1 = +x == null;
const value2 = condition ? x : {} || DEFAULT;
const value3 = !foo == null;
const value4 = new Boolean(foo) === true;
const objIsEmpty = someObj === {};
const arrIsEmpty = someArr === [];
Disallow ternary operators when simpler alternatives exist
https://eslint.org/docs/latest/rules/no-unneeded-ternary
π Examples of correct code
var a = x === 2 ? "Yes" : "No";
var a = x !== false;
var a = x ? "Yes" : "No";
var a = x ? y : x;
f(x || 1);
π Examples of incorrect code
var a = x === 2 ? true : false;
var a = x ? true : false;
f(x ? x : 1);
Disallow negating the left operand of relational operators
https://eslint.org/docs/latest/rules/no-unsafe-negation
π Examples of correct code
if (!(key in object)) {
// key is not in object
}
if (!(obj instanceof Ctor)) {
// obj is not an instance of Ctor
}
π Examples of incorrect code
if (!key in object) {
// operator precedence makes it equivalent to (!key) in object
// and type conversion makes it equivalent to (key ? "false" : "true") in object
}
if (!obj instanceof Ctor) {
// operator precedence makes it equivalent to (!obj) instanceof Ctor
// and it equivalent to always false since boolean values are not objects.
}
Enforce consistent case for text encoding identifiers
π Examples of correct code
await fs.readFile(file, 'utf8');
await fs.readFile(file, 'ascii');
const string = buffer.toString('utf8');
π Examples of incorrect code
await fs.readFile(file, 'UTF-8');
await fs.readFile(file, 'ASCII');
const string = buffer.toString('utf-8');
Parameters should be passed in the correct order
https://sonarsource.github.io/rspec/#/rspec/S2234/javascript
π Examples of correct code
function divide(divisor, dividend) {
return divisor/dividend;
}
function doTheThing() {
var divisor = 15;
var dividend = 5;
var result = divide(divisor, dividend);
//...
}
π Examples of incorrect code
function divide(divisor, dividend) {
return divisor/dividend;
}
function doTheThing() {
var divisor = 15;
var dividend = 5;
var result = divide(dividend, divisor); // Noncompliant; operation succeeds, but result is unexpected
//...
}
A test case without assertions ensures only that no exceptions are thrown. Beyond basic runnability, it ensures nothing about the behavior of the code under test.
https://sonarsource.github.io/rspec/#/rspec/S2699/javascript
π Examples of correct code
const expect = require('chai').expect;
describe("Has assertions", function() {
it("tests a string", function() {
const str = "";
expect(str).to.be.a('string');
});
});
π Examples of incorrect code
const expect = require('chai').expect;
describe("No assertion", function() {
it("doesn't test anything", function() { // Noncompliant
const str = "";
});
});
A test case without assertions ensures only that no exceptions are thrown. Beyond basic runnability, it ensures nothing about the behavior of the code under test.
https://sonarsource.github.io/rspec/#/rspec/S2699/javascript
π Examples of correct code
const expect = require('chai').expect;
describe("uncertain assertions", function() {
const throwsTypeError = () => { throw new TypeError() }
it("uses chai 'expect'", function() {
expect(throwsTypeError).to.throw(TypeError)
expect({a: 42}).to.not.have.any.keys('b', 'c');
expect({a: 21}).to.not.have.property('b');
expect({a: 21}).to.not.have.ownPropertyDescriptor('b');
expect([21, 42]).to.not.include(1).and.not.include(2);
var myObj = { value: 1 }
const incThree = () => { myObj.value += 3; };
const decThree = () => { myObj.value -= 3; };
const doNothing = () => {};
expect(incThree).to.increase(myObj, 'value').by(3);
expect(decThree).to.decrease(myObj, 'value').by(3);
expect(decThree).to.decrease(myObj, 'value').by(3);
expect(incThree).to.increase(myObj, 'value').by(3);
expect(doNothing).to.not.change(myObj, 'value');
expect(incThree).to.increase(myObj, 'value').by(3);
let toCheck;
// Either of the following is valid
expect(toCheck).to.be.a('string');
expect(toCheck).to.be.NaN;
expect(toCheck).to.equal(Infinity);
expect(toCheck).to.equal(-Infinity);
});
});
π Examples of incorrect code
const expect = require('chai').expect;
describe("uncertain assertions", function() {
const throwsTypeError = () => { throw new TypeError() }
it("uses chai 'expect'", function() {
expect(throwsTypeError).to.not.throw(ReferenceError) // Noncompliant
expect({a: 42}).to.not.include({b: 10, c: 20}); // Noncompliant
expect({a: 21}).to.not.have.property('b', 42); // Noncompliant
expect({a: 21}).to.not.have.ownPropertyDescriptor('b', { // Noncompliant
configurable: true,
enumerable: true,
writable: true,
value: 42,
});
expect([21, 42]).to.not.have.members([1, 2]); // Noncompliant
var myObj = { value: 1 }
const incThree = () => { myObj.value += 3; };
const decThree = () => { myObj.value -= 3; };
const doNothing = () => {};
expect(incThree).to.change(myObj, 'value').by(3); // Noncompliant
expect(decThree).to.change(myObj, 'value').by(3); // Noncompliant
expect(decThree).to.not.increase(myObj, 'value'); // Noncompliant
expect(incThree).to.not.decrease(myObj, 'value'); // Noncompliant
expect(doNothing).to.not.increase(myObj, 'value'); // Noncompliant
expect(doNothing).to.not.decrease(myObj, 'value'); // Noncompliant
expect(incThree).to.increase(myObj, 'value').but.not.by(1); // Noncompliant
let toCheck;
expect(toCheck).to.not.be.finite; // Noncompliant
});
});
Timeout should be disabled by setting it to "0".
https://sonarsource.github.io/rspec/#/rspec/S6080/javascript
π Examples of correct code
describe("testing this.timeout", function() {
it("doesn't disable the timeout", function(done) {
this.timeout(1000);
});
});
π Examples of incorrect code
describe("testing this.timeout", function() {
it("unexpectedly disables the timeout", function(done) {
this.timeout(2147483648); // Noncompliant
});
});
describe("testing this.timeout", function() {
it("disables the timeout as expected", function(done) {
this.timeout(0);
});
});
Empty static blocks, while not technically errors, usually occur due to refactoring that wasnβt completed. They can cause confusion when reading code.
https://eslint.org/docs/latest/rules/no-empty-static-block
π Examples of correct code
class Foo {
static {
bar();
}
}
class Foo {
static {
// comment
}
}
π Examples of incorrect code
class Foo {
static {}
}
The switch statement in JavaScript is one of the more error-prone constructs of the language thanks in part to the ability to βfall throughβ from one case to the next. For example:
Use // falls through
comments to run multiple cases
https://eslint.org/docs/latest/rules/no-fallthrough
π Examples of correct code
switch(foo) {
case 1:
doSomething();
break;
case 2:
doSomething();
}
function bar(foo) {
switch(foo) {
case 1:
doSomething();
return;
case 2:
doSomething();
}
}
switch(foo) {
case 1:
doSomething();
throw new Error("Boo!");
case 2:
doSomething();
}
switch(foo) {
case 1:
case 2:
doSomething();
}
switch(foo) {
case 1:
doSomething();
// falls through
case 2:
doSomething();
}
switch(foo) {
case 1: {
doSomething();
// falls through
}
case 2: {
doSomethingElse();
}
}
π Examples of incorrect code
switch(foo) {
case 1:
doSomething();
case 2:
doSomething();
}
Octal literals are numerals that begin with a leading zero, such as:
https://eslint.org/docs/latest/rules/no-octal
π Examples of correct code
var test = 71 + 5; // 76
π Examples of incorrect code
var num = 071; // 57
var result = 5 + 07;
var test = 071 + 5; // 62
As of the ECMAScript 5 specification, octal escape sequences in string literals are deprecated and should not be used. Unicode escape sequences should be used instead.
https://eslint.org/docs/latest/rules/no-octal-escape
π Examples of correct code
var foo = "Copyright \u00A9"; // unicode
var foo = "Copyright \xA9"; // hexadecimal
π Examples of incorrect code
var foo = "Copyright \251";
JavaScript environments contain a number of built-in global variables, such as window in browsers and process in Node.js. In almost all cases, you donβt want to assign a value to these global variables as doing so could result in losing access to important functionality. For example, you probably donβt want to do this in browser code:
https://eslint.org/docs/latest/rules/no-global-assign
π Examples of correct code
a = 1
const b = 1
b = 2
π Examples of incorrect code
Object = null
undefined = 1
window = {}
length = 1
top = 1
This rule disallows lexical declarations (let, const, function and class) in case/default clauses. The reason is that the lexical declaration is visible in the entire switch block but it only gets initialized when it is assigned, which will only happen if the case where it is defined is reached.
https://eslint.org/docs/latest/rules/no-case-declarations
π Examples of correct code
// Declarations outside switch-statements are valid
const a = 0;
switch (foo) {
// The following case clauses are wrapped into blocks using brackets
case 1: {
let x = 1;
break;
}
case 2: {
const y = 2;
break;
}
case 3: {
function f() {}
break;
}
case 4:
// Declarations using var without brackets are valid due to function-scope hoisting
var z = 4;
break;
default: {
class C {}
}
}
π Examples of incorrect code
switch (foo) {
case 1:
let x = 1;
break;
case 2:
const y = 2;
break;
case 3:
function f() {}
break;
default:
class C {}
}
void in TypeScript refers to a function return that is meant to be ignored. Attempting to use a void-typed value, such as storing the result of a called function in a variable, is often a sign of a programmer error.
π Examples of correct code
// just a regular void function in a statement position
alert('Hello, world!');
// this function returns a boolean value so it's ok
const response = confirm('Are you sure?');
console.log(confirm('Are you sure?'));
// now it's obvious that `postMessage` doesn't return any response
promise.then(value => {
window.postMessage(value);
});
// now it's explicit that we want to log the error and return early
function doSomething() {
if (!somethingToDo) {
console.error('Nothing to do!');
return;
}
console.log('Doing a thing...');
}
// using logical expressions for their side effects is fine
cond && console.log('true');
cond || console.error('false');
cond ? console.log('true') : console.error('false');
π Examples of incorrect code
// somebody forgot that `alert` doesn't return anything
const response = alert('Are you sure?');
console.log(alert('Are you sure?'));
// it's not obvious whether the chained promise will contain the response (fixable)
promise.then(value => window.postMessage(value));
// it looks like we are returning the result of `console.error` (fixable)
function doSomething() {
if (!somethingToDo) {
return console.error('Nothing to do!');
}
console.log('Doing a thing...');
}
Although TypeScript supports duplicate enum member values, people usually expect members to have unique values within the same enum. Duplicate values can lead to bugs that are hard to track down.
π Examples of correct code
enum E {
A = 0,
B = 1,
}
enum E {
A = 'A',
B = 'B',
}
π Examples of incorrect code
enum E {
A = 0,
B = 0,
}
enum E {
A = 'A',
B = 'A',
}
A "floating" Promise is one that is created without any code set up to handle any errors it might throw. Floating Promises can cause several issues, such as improperly sequenced operations, ignored Promise rejections, and more.
π Examples of correct code
const promise = new Promise((resolve, reject) => resolve('value'));
await promise;
async function returnsPromise() {
return 'value';
}
returnsPromise()
.then(() => {})
.catch(() => {});
Promise.reject('value').catch(() => {});
Promise.reject('value').finally(() => {});
π Examples of incorrect code
const promise = new Promise((resolve, reject) => resolve('value'));
promise;
async function returnsPromise() {
return 'value';
}
returnsPromise().then(() => {});
Promise.reject('value').catch();
Promise.reject('value').finally();
void in TypeScript refers to a function return that is meant to be ignored. Attempting to use a void type outside of a return type or generic type argument is often a sign of programmer error.
π Examples of correct code
type NoOp = () => void;
function noop(): void {}
let trulyUndefined = void 0;
async function promiseMeSomething(): Promise<void> {}
type stillVoid = void | never;
π Examples of incorrect code
type PossibleValues = string | number | void;
type MorePossibleValues = string | ((number & any) | (string | void));
function logSomething(thing: void) {}
function printArg<T = void>(arg: T) {}
logAndReturn<void>(undefined);
interface Interface {
lambda: () => void;
prop: void;
}
class MyClass {
private readonly propName: void;
}
The ?? nullish coalescing runtime operator allows providing a default value when dealing with null or undefined. Using a ! non-null assertion type operator in the left operand of a nullish coalescing operator is redundant, and likely a sign of programmer error or confusion over the two operators.
π Examples of correct code
foo ?? bar;
foo ?? bar!;
foo!.bazz ?? bar;
foo!.bazz ?? bar!;
foo() ?? bar;
// This is considered correct code because there's no way for the user to satisfy it.
let x: string;
x! ?? '';
π Examples of incorrect code
foo! ?? bar;
foo.bazz! ?? bar;
foo!.bazz! ?? bar;
foo()! ?? bar;
let x!: string;
x! ?? '';
let x: string;
x = foo();
x! ?? '';
?. optional chain expressions provide undefined if an object is null or undefined. Using a ! non-null assertion to assert the result of an ?. optional chain expression is non-nullable is likely wrong.
Most of the time, either the object was not nullable and did not need the ?. for its property lookup, or the ! is incorrect and introducing a type safety hole.
π Examples of correct code
foo?.bar;
foo?.bar();
foo.bar!;
π Examples of incorrect code
foo?.bar!;
foo?.bar()!;
TypeScript's "declaration merging" supports merging separate declarations with the same name.
π Examples of correct code
interface Foo {}
class Bar implements Foo {}
namespace Baz {}
namespace Baz {}
enum Baz {}
namespace Qux {}
function Qux() {}
π Examples of incorrect code
interface Foo {}
class Foo {}
An empty export {} statement is sometimes useful in TypeScript code to turn a file that would otherwise be a script file into a module file.
π Examples of correct code
export const value = 'Hello, world!';
export {};
// or
import 'some-other-module';
export {};
π Examples of incorrect code
export const value = 'Hello, world!';
// or
import 'some-other-module';
JavaScript will call toString() on an object when it is converted to a string, such as when + adding to a string or in ${} template literals. The default Object .toString() returns "[object Object]", which is often not what was intended. This rule reports on values used in a template literal string that aren't strings. primitives and don't define a more useful .toString() method.
π Examples of correct code
const arg = 'foo';
const msg1 = `arg = ${arg}`;
const msg2 = `arg = ${arg || 'default'}`;
const stringWithKindProp: string & { _kind?: 'MyString' } = 'foo';
const msg3 = `stringWithKindProp = ${stringWithKindProp}`;
const arg = 123;
const msg1 = `arg = ${arg}`;
const msg2 = `arg = ${arg || 'zero'}`;
const arg = true;
const msg1 = `arg = ${arg}`;
const msg2 = `arg = ${arg || 'not truthy'}`;
π Examples of incorrect code
const arg1 = [1, 2];
const msg1 = `arg1 = ${arg1}`;
const arg2 = { name: 'Foo' };
const msg2 = `arg2 = ${arg2 || null}`;
Returning an awaited promise can make sense for better stack trace information as well as for consistent error handling (returned promises will not be caught in an async function try/catch).
π Examples of correct code
async function validInTryCatch1() {
try {
return await Promise.resolve('try');
} catch (e) {}
}
async function validInTryCatch2() {
try {
throw new Error('error');
} catch (e) {
return Promise.resolve('catch');
}
}
async function validInTryCatch3() {
try {
throw new Error('error');
} catch (e) {
return await Promise.resolve('catch');
} finally {
console.log('cleanup');
}
}
async function validInTryCatch4() {
try {
throw new Error('error');
} catch (e) {
throw new Error('error2');
} finally {
return Promise.resolve('finally');
}
}
async function validInTryCatch5() {
return Promise.resolve('try');
}
async function validInTryCatch6() {
return 'value';
}
π Examples of incorrect code
async function invalidInTryCatch1() {
try {
return Promise.resolve('try');
} catch (e) {}
}
async function invalidInTryCatch2() {
try {
throw new Error('error');
} catch (e) {
return await Promise.resolve('catch');
}
}
async function invalidInTryCatch3() {
try {
throw new Error('error');
} catch (e) {
return Promise.resolve('catch');
} finally {
console.log('cleanup');
}
}
async function invalidInTryCatch4() {
try {
throw new Error('error');
} catch (e) {
throw new Error('error2');
} finally {
return await Promise.resolve('finally');
}
}
async function invalidInTryCatch5() {
return await Promise.resolve('try');
}
async function invalidInTryCatch6() {
return await 'value';
}
When working with union types in TypeScript, it's common to want to write a switch statement intended to contain a case for each constituent (possible type in the union). However, if the union type changes, it's easy to forget to modify the cases to account for any new types.
π Examples of correct code
type Day =
| 'Monday'
| 'Tuesday'
| 'Wednesday'
| 'Thursday'
| 'Friday'
| 'Saturday'
| 'Sunday';
const day = 'Monday' as Day;
let result = 0;
switch (day) {
case 'Monday':
result = 1;
break;
case 'Tuesday':
result = 2;
break;
case 'Wednesday':
result = 3;
break;
case 'Thursday':
result = 4;
break;
case 'Friday':
result = 5;
break;
case 'Saturday':
result = 6;
break;
case 'Sunday':
result = 7;
break;
}
// OR default
switch (day) {
case 'Monday':
result = 1;
break;
default:
result = 42;
}
π Examples of incorrect code
type Day =
| 'Monday'
| 'Tuesday'
| 'Wednesday'
| 'Thursday'
| 'Friday'
| 'Saturday'
| 'Sunday';
const day = 'Monday' as Day;
let result = 0;
switch (day) {
case 'Monday':
result = 1;
break;
}
Most checks against an indexOf call against an array compare it with -1 because 0 is a valid index. Any checks which look for values >0 ignore the first element, which is likely a bug. If youβre merely checking the presence of the element, consider using includes instead. Before using includes method make sure that your browser version is supporting it.
https://sonarsource.github.io/rspec/#/rspec/S2692/javascript
π Examples of correct code
var color = "blue";
var name = "ishmael";
var arr = [color, name];
if (arr.indexOf("blue") >= 0) {
// ...
}
if (arr.includes("blue")) {
// ...
}
π Examples of incorrect code
var color = "blue";
var name = "ishmael";
var arr = [color, name];
if (arr.indexOf("blue") > 0) { // Noncompliant
// ...
}
Function returns should not be invariant
https://sonarsource.github.io/rspec/#/rspec/S3516/javascript
π Examples of correct code
function foo(a) { // Noncompliant
let b = 12;
if (a) {
return b + a; // Not equals
}
return b;
}
π Examples of incorrect code
function foo(a) { // Noncompliant
let b = 12;
if (a) {
return b;
}
return b;
}
Constructor functions, which create new object instances, must only be called with new. Non-constructor functions must not. Mixing these two usages could lead to unexpected results at runtime.
https://sonarsource.github.io/rspec/#/rspec/S3686/javascript
π Examples of correct code
function getNum() {
return 5;
}
function Num(numeric, alphabetic) {
this.numeric = numeric;
this.alphabetic = alphabetic;
}
var myFirstNum = getNum();
var myNumObj1 = new Num(1, "A");
π Examples of incorrect code
function getNum() {
return 5;
}
function Num(numeric, alphabetic) {
this.numeric = numeric;
this.alphabetic = alphabetic;
}
var my2ndNum = new getNum(); // Noncompliant. An empty object is returned, NOT 5
var myNumObj2 = Num(); // Noncompliant. undefined is returned, NOT an object
Having all branches in a switch or if chain with the same implementation is an error. Either a copy-paste error was made and something different should be executed
π Examples of correct code
if (b == 0) { // Noncompliant
doOneMoreThing();
} else {
doOneMoreThing();
}
let a = b === 0 ? getValue() : getDefaultValue(); // Noncompliant
switch (i) { // Noncompliant
case 1:
doSomethingOne();
break;
case 2:
doSomethingTwo();
break;
case 3:
default:
doSomething();
}
π Examples of incorrect code
if (b == 0) { // Noncompliant
doOneMoreThing();
} else {
doSomethingElse();
}
let a = b === 0 ? getValue() : getValue(); // Noncompliant
switch (i) { // Noncompliant
case 1:
doSomething();
break;
case 2:
doSomething();
break;
case 3:
doSomething();
break;
default:
doSomething();
}
Redundant type aliases should not be used
https://sonarsource.github.io/rspec/#/rspec/S6564/javascript
π Examples of correct code
function isPalindrom(s: string): boolean {
return s === s.split('').reverse().join('');
}
π Examples of incorrect code
type MyString = string;
type MyBoolean = boolean;
function isPalindrom(s: MyString): MyBoolean {
return s === s.split('').reverse().join('');
}
It is highly suspicious when a value is saved for a key or index and then unconditionally overwritten. Such replacements are likely in error.
https://github.com/SonarSource/eslint-plugin-sonarjs/blob/HEAD/docs/rules/no-element-overwrite.md
π Examples of correct code
fruits[1] = "banana";
myMap.set("key", 1);
mySet.add(1);
π Examples of incorrect code
fruits[1] = "banana";
fruits[1] = "apple"; // Noncompliant - value on index 1 is overwritten
myMap.set("key", 1);
myMap.set("key", 2); // Noncompliant - value for key "key" is replaced
mySet.add(1);
mySet.add(1); // Noncompliant - element is already in the set
When a collection is empty it makes no sense to access or iterate it. Doing so anyway is surely an error; either population was accidentally omitted or the developer doesnβt understand the situation.
https://github.com/SonarSource/eslint-plugin-sonarjs/blob/HEAD/docs/rules/no-empty-collection.md
π Examples of correct code
let strings = [ ...anotherArray ];
if (strings.includes("foo")) {}
for (str of strings) {}
strings.forEach(str => doSomething(str));
π Examples of incorrect code
let strings = [];
if (strings.includes("foo")) {} // Noncompliant
for (str of strings) {} // Noncompliant
strings.forEach(str => doSomething(str)); // Noncompliant
You can easily call a JavaScript function with more arguments than the function needs, but the extra arguments will be just ignored by function execution.
https://github.com/SonarSource/eslint-plugin-sonarjs/blob/HEAD/docs/rules/no-extra-arguments.md
π Examples of correct code
function doSomething(a, b) {
compute(arguments);
}
doSomething(1, 2, 3);
// Or
function say(a, b) {
print(a + " " + b);
}
say("hello", "world");
π Examples of incorrect code
function say(a, b) {
print(a + " " + b);
}
say("hello", "world", "!"); // Noncompliant; last argument is not used
Using the same value on either side of a binary operator is almost always a mistake. In the case of logical operators, it is either a copy/paste error and therefore a bug, or it is simply wasted code, and should be simplified. In the case of bitwise operators and most binary mathematical operators, having the same value on both sides of an operator yields predictable results, and should be simplified.
π Examples of correct code
if (a == b) {
doX();
}
if (a > b) {
doW();
}
var j = 1; //always 1
var k = 0; //always 0
π Examples of incorrect code
if (a == b && a == b) { // if the first one is true, the second one is too
doX();
}
if (a > a) { // always false
doW();
}
var j = 5 / 5; //always 1
var k = 5 - 5; //always 0
When the call to a function doesnβt have any side effects, what is the point of making the call if the results are ignored? In such case, either the function call is useless and should be dropped or the source code doesnβt behave as expected.
https://github.com/SonarSource/eslint-plugin-sonarjs/blob/HEAD/docs/rules/no-ignored-return.md
π Examples of correct code
let char = 'hello'.lastIndexOf('e');
π Examples of incorrect code
'hello'.lastIndexOf('e'); // Noncompliant
If a function does not return anything, it makes no sense to use its output. Specifically, passing it to another function, or assigning its "result" to a variable is probably a bug because such functions return undefined, which is probably not what was intended.
π Examples of correct code
function foo() {
console.log("Hello, World!");
}
foo();
π Examples of incorrect code
function foo() {
console.log("Hello, World!");
}
a = foo();
The size of a collection and the length of an array are always greater than or equal to zero. So testing that a size or length is greater than or equal to zero doesn't make sense, since the result is always true. Similarly testing that it is less than zero will always return false. Perhaps the intent was to check the non-emptiness of the collection or array instead.
π Examples of correct code
if (someSet.size > 0) {...}
if (someMap.size == 0) {...}
const result = someArray.length > 0;
π Examples of incorrect code
if (someSet.size >= 0) {...} // Noncompliant
if (someMap.size < 0) {...} // Noncompliant
const result = someArray.length >= 0; // Noncompliant
If a boolean expression doesnβt change the evaluation of the condition, then it is entirely unnecessary, and can be removed. If it is gratuitous because it does not match the programmerβs intent, then itβs a bug and the expression should be fixed.
π Examples of correct code
if (a) {
if (b) {
doSomething();
}
}
// or
if (a) {
doSomething();
}
π Examples of incorrect code
if (a) {
if (a) { // Noncompliant
doSomething();
}
}
// Or
if (a) {
console.log("anything");
if (a) { // Noncompliant
doSomething();
}
}
When a collection is populated but its contents are never used, then it is surely some kind of mistake. Either refactoring has rendered the collection moot, or an access is missing.
https://github.com/SonarSource/eslint-plugin-sonarjs/blob/HEAD/docs/rules/no-unused-collection.md
π Examples of correct code
function getLength(a, b, c) {
return a.length + b.length + c.length;
}
π Examples of incorrect code
function getLength(a, b, c) {
const strings = []; // Noncompliant
strings.push(a);
strings.push(b);
strings.push(c);
return a.length + b.length + c.length;
}
Check a valid typescript and docblock
https://github.com/ODGodinho/ODGEslintPlugin#no-inconsistent-docblock
π Examples of correct code
/**
* Valid Param
*
* @param {string} param
*/
function name(param: string) {
}
/**
* Valid return
*
* @returns {string}
*/
function name2(): string {
}
π Examples of incorrect code
/**
* Valid Param
*
* @param {number} param
*/
function name(param: string) {
}
/**
* Valid return
*
* @returns {number}
*/
function name2(): string {
}
add suport yaml and json files
FAQs
Linter for JavaScript And Typescript project
The npm package @odg/eslint-config receives a total of 28 weekly downloads. As such, @odg/eslint-config popularity was classified as not popular.
We found that @odg/eslint-config demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.Β It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
ECMAScript 2025 introduces Iterator Helpers, Set methods, JSON modules, and more in its latest spec update approved by Ecma in June 2025.
Security News
A new Node.js homepage button linking to paid support for EOL versions has sparked a heated discussion among contributors and the wider community.
Research
North Korean threat actors linked to the Contagious Interview campaign return with 35 new malicious npm packages using a stealthy multi-stage malware loader.