eslint-config-alloy

English/简体中文

Rule Description

Incorrect Example

Correct Example

accessor-pairs  #

enforce getter and setter pairs in objects and classes

Options:
["error", {
    "setWithoutGet": true,
    "getWithoutSet": false
}]
const foo = {
  set bar(value) {
    this.barValue = 'bar ' + value;
  },
};
const foo = {
  set bar(value) {
    this.barValue = 'bar ' + value;
  },
  get bar() {
    return this.barValue;
  },
};
const bar = {
  get foo() {
    return this.fooValue;
  },
};
array-callback-return  #

enforce return statements in callbacks of array methods

const foo = [1, 2, 3].map((num) => {
  console.log(num * num);
});
const foo = [1, 2, 3].map((num) => {
  return num * num;
});
arrow-body-style  🔧#

Require braces in arrow function body

代码格式问题,最好由 Prettier 解决

block-scoped-var  #

enforce the use of variables within the scope they are defined

已经禁止使用 var 了

camelcase  #

Enforce camelCase naming convention

很多 api 或文件名都不是 camelCase 风格的

capitalized-comments  🔧#

enforce or disallow capitalization of the first letter of a comment

class-methods-use-this  #

enforce that class methods utilize this

complexity  #

enforce a maximum cyclomatic complexity allowed in a program

https://en.wikipedia.org/wiki/Cyclomatic_complexity

Options:
["error", {
    "max": 20
}]
function foo() {
  if (i === 1) console.log(i);
  if (i === 2) console.log(i);
  if (i === 3) console.log(i);
  if (i === 4) console.log(i);
  if (i === 5) console.log(i);
  if (i === 6) console.log(i);
  if (i === 7) console.log(i);
  if (i === 8) console.log(i);
  if (i === 9) console.log(i);
  if (i === 10) console.log(i);
  if (i === 11) console.log(i);
  if (i === 12) console.log(i);
  if (i === 13) console.log(i);
  if (i === 14) console.log(i);
  if (i === 15) console.log(i);
  if (i === 16) console.log(i);
  if (i === 17) console.log(i);
  if (i === 18) console.log(i);
  if (i === 19) console.log(i);
  if (i === 20) console.log(i);
}
function foo() {
  if (i === 1) console.log(i);
  if (i === 2) console.log(i);
  if (i === 3) console.log(i);
  if (i === 4) console.log(i);
  if (i === 5) console.log(i);
  if (i === 6) console.log(i);
  if (i === 7) console.log(i);
  if (i === 8) console.log(i);
  if (i === 9) console.log(i);
  if (i === 10) console.log(i);
  bar(i);
}
function bar(i) {
  if (i === 11) console.log(i);
  if (i === 12) console.log(i);
  if (i === 13) console.log(i);
  if (i === 14) console.log(i);
  if (i === 15) console.log(i);
  if (i === 16) console.log(i);
  if (i === 17) console.log(i);
  if (i === 18) console.log(i);
  if (i === 19) console.log(i);
  if (i === 20) console.log(i);
}
consistent-return  #

require return statements to either always or never specify values

缺少 TypeScript 的支持,类型判断是不准确的

consistent-this  #

enforce consistent naming when capturing the current execution context

constructor-super  #

require super() calls in constructors

class Foo extends Bar {
  constructor() {}
}
class Foo extends Bar {
  constructor() {
    super();
  }
}
default-case  #

require default cases in switch statements

default-case-last  #

Enforce default parameters to be last

switch (foo) {
  default:
    bar();
    break;
  case 1:
    baz();
    break;
}
switch (foo) {
  case 1:
    baz();
    break;
  default:
    bar();
    break;
}
default-param-last  #

enforce default parameters to be last

dot-notation  🔧#

enforce dot notation whenever possible

当需要写一系列属性的时候,可以更统一

eqeqeq  🔧#

require the use of === and !==

Options:["error", "always"]
if (foo == 1) {
}
if (bar != null) {
}
if (foo === 1) {
}
if (bar !== null) {
}
for-direction  #

enforce "for" loop update clause moving the counter in the right direction.

for (let i = 0; i < 10; i--) {
  // do something
}
for (let i = 0; i < 10; i++) {
  // do something
}
func-name-matching  #

require function names to match the name of the variable or property to which they are assigned

Options:["error", "always"]
const foo = function bar() {};
const foo = function () {};
const bar = function bar() {};
func-names  #

require or disallow named function expressions

func-style  #

enforce the consistent use of either function declarations or expressions

getter-return  #

enforce return statements in getters

const user = {
  get name() {
    // do something
  },
};
class User {
  get name() {
    return;
  }
}
const user = {
  get name() {
    return 'Alex';
  },
};
class User {
  get name() {
    return this.name;
  }
}
grouped-accessor-pairs  #

Require grouped accessor pairs in object literals and classes

const foo = {
  set bar(value) {
    this.barValue = 'bar ' + value;
  },
  baz: 1,
  get bar() {
    return this.barValue;
  },
};
const foo = {
  set bar(value) {
    this.barValue = 'bar ' + value;
  },
  get bar() {
    return this.barValue;
  },
  baz: 1,
};
guard-for-in  #

require for-in loops to include an if statement

for (key in foo) {
  doSomething(key);
}
for (key in foo) {
  if (Object.prototype.hasOwnProperty.call(foo, key)) {
    doSomething(key);
  }
}
id-denylist  #

disallow specified identifiers

id-length  #

enforce minimum and maximum identifier lengths

id-match  #

require identifiers to match a specified regular expression

init-declarations  #

require or disallow initialization in variable declarations

line-comment-position  #

enforce position of line comments

lines-between-class-members  #

require or disallow an empty line between class members

有时为了紧凑需要挨在一起,有时为了可读性需要空一行

logical-assignment-operators  🔧#

Require or disallow logical assignment logical operator shorthand

max-classes-per-file  #

enforce a maximum number of classes per file

max-depth  #

enforce a maximum depth that blocks can be nested

Options:["error", 5]
function foo() {
  if (true) {
    if (true) {
      if (true) {
        if (true) {
          if (true) {
            if (true) {
            }
          }
        }
      }
    }
  }
}
function foo() {
  if (true) {
    if (true) {
      if (true) {
        if (true) {
          if (true) {
          }
        }
      }
    }
  }
}
max-lines  #

enforce a maximum number of lines per file

max-lines-per-function  #

enforce a maximum number of line of code in a function

max-nested-callbacks  #

enforce a maximum depth that callbacks can be nested

Options:["error", 3]
foo(() => {
  bar(() => {
    baz(() => {
      qux(() => {});
    });
  });
});
foo(async () => {
  await bar();
  await baz();
  await qux();
});
max-params  #

enforce a maximum number of parameters in function definitions

Options:["error", 3]
function foo(a1, a2, a3, a4) {}
function foo(a1, a2, a3) {}
function bar({ a1, a2, a3, a4 }) {}
max-statements  #

enforce a maximum number of statements allowed in function blocks

max-statements-per-line  #

enforce a maximum number of statements allowed per line

multiline-comment-style  #

enforce a particular style for multiline comments

能写注释已经不容易了,不需要限制太多

new-cap  #

require constructor names to begin with a capital letter

Options:
["error", {
    "newIsCap": true,
    "capIsNew": false,
    "properties": true
}]
new foo();
new foo.bar();
new Foo();
new foo.Bar();
Foo();
no-alert  #

disallow the use of alert, confirm, and prompt

no-array-constructor  #

disallow Array constructors

参数为一个时表示创建一个指定长度的数组,比较常用
参数为多个时表示创建一个指定内容的数组,此时可以用数组字面量实现,不必使用构造函数

const foo = Array(0, 1, 2); // [0, 1, 2]
const bar = new Array(0, 1, 2); // [0, 1, 2]
const foo = [0, 1, 2];
Array(3); // [empty × 3]
new Array(3); // [empty × 3]
Array(3).fill('foo'); // ["foo", "foo", "foo"]
new Array(3).fill('foo'); // ["foo", "foo", "foo"]
no-async-promise-executor  #

disallow using an async function as a Promise executor

出现这种情况时,一般不需要使用 new Promise 实现异步了

new Promise(async (resolve) => {
  setTimeout(resolve, 1000);
});
new Promise((resolve) => {
  setTimeout(resolve, 1000);
});
no-await-in-loop  #

disallow await inside of loops

要求太严格了,有时需要在循环中写 await

no-bitwise  #

disallow bitwise operators

no-caller  #

disallow the use of arguments.caller or arguments.callee

它们是已废弃的语法

function foo(n) {
  if (n <= 0) {
    return;
  }
  arguments.callee(n - 1);
}
function foo(n) {
  if (n <= 0) {
    return;
  }
  foo(n - 1);
}
no-case-declarations  #

disallow lexical declarations in case clauses

switch (foo) {
  case 1:
    const x = 1;
    break;
}
switch (foo) {
  case 1: {
    const x = 1;
    break;
  }
}
no-class-assign  #

disallow reassigning class members

class Foo {}
Foo = {};
class Foo {}
no-compare-neg-zero  #

disallow comparing against -0

if (foo === -0) {
}
if (foo === 0) {
}
no-cond-assign  #

disallow assignment operators in conditional expressions

Options:["error", "except-parens"]
if (foo = 0) {
}
if (foo === 0) {
}
if (bar === (foo = 0)) {
}
no-console  #

disallow the use of console

no-const-assign  #

disallow reassigning const variables

const foo = 1;
foo = 2;
let foo = 1;
foo = 2;

for (const bar in [1, 2, 3]) {
  console.log(bar);
}
no-constant-binary-expression  #

disallow expressions where the operation doesn't affect the value

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 === [];
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;
no-constant-condition  #

disallow constant expressions in conditions

Options:
["error", {
    "checkLoops": false
}]
if (true) {
}
const foo = 0 ? 'bar' : 'baz';
for (; true; ) {
  if (foo === 0) break;
}
while (true) {
  if (foo === 0) break;
}
no-constructor-return  #

Disallow returning value in constructor

class Foo {
  constructor(bar) {
    this.bar = bar;
    return bar;
  }
}
class Foo {
  constructor(bar) {
    if (!bar) {
      return;
    }
    this.bar = bar;
  }
}
no-continue  #

disallow continue statements

no-control-regex  #

disallow control characters in regular expressions

几乎不会遇到这种场景

no-debugger  #

disallow the use of debugger

if (foo) {
  debugger;
}
if (foo) {
  // debugger;
}
no-delete-var  #

disallow deleting variables

编译阶段就会报错了

no-div-regex  🔧#

disallow division operators explicitly at the beginning of regular expressions

有代码高亮的话,在阅读这种代码时,也完全不会产生歧义或理解上的困难

no-dupe-args  #

disallow duplicate arguments in function definitions

编译阶段就会报错了

no-dupe-class-members  #

disallow duplicate class members

class Foo {
  bar() {}
  bar() {}
}
class Foo {
  bar() {}
  baz() {}
}
no-dupe-else-if  #

Disallow duplicate conditions in if-else-if chains

if (foo) {
  console.log(foo);
} else if (foo) {
  console.log(bar);
}
if (foo) {
  console.log(foo);
} else if (bar) {
  console.log(bar);
}
no-dupe-keys  #

disallow duplicate keys in object literals

const foo = {
  bar: 1,
  bar: 2,
};
const foo = {
  bar: 1,
  baz: 2,
};
no-duplicate-case  #

disallow duplicate case labels

switch (foo) {
  case 1:
    break;
  case 2:
    break;
  case 1:
    break;
}
switch (foo) {
  case 1:
    break;
  case 2:
    break;
  case 3:
    break;
}
no-duplicate-imports  #

disallow duplicate module imports

no-else-return  🔧#

disallow else blocks after return statements in if statements

else 中使用 return 可以使代码结构更清晰

no-empty  #

disallow empty block statements

Options:
["error", {
    "allowEmptyCatch": true
}]
if (foo) {
}
if (foo) {
  // do something
}
try {
  // do something
} catch (e) {}
no-empty-character-class  #

disallow empty character classes in regular expressions

const reg = /abc[]/;
const reg = /abc[a-z]/;
no-empty-function  #

disallow empty functions

有时需要将一个空函数设置为某个项的默认值

no-empty-pattern  #

disallow empty destructuring patterns

const {} = foo;
const { bar } = foo;
no-empty-static-block  #

Disallow empty static blocks

no-eq-null  #

disallow null comparisons without type-checking operators

if (foo == null) {
}
if (foo === null) {
}
no-eval  #

disallow the use of eval()

eval('const foo = 0');
const foo = 0;
no-ex-assign  #

disallow reassigning exceptions in catch clauses

try {
} catch (e) {
  e = 10;
}
try {
} catch (e) {
  console.error(e);
}
no-extend-native  #

disallow extending native types

修改原生对象可能会与将来版本的 js 冲突

Array.prototype.flat = function () {
  // do something
};

[1, [2, 3]].flat();
function flat(arr) {
  // do something
}

flat([1, [2, 3]]);
no-extra-bind  🔧#

disallow unnecessary calls to .bind()

(function () {
  foo();
}).bind(bar);
(function () {
  this.foo();
}).bind(bar);
no-extra-boolean-cast  🔧#

disallow unnecessary boolean casts

if (!!foo) {
}
if (Boolean(foo)) {
}
if (foo) {
}
if (!foo) {
}
no-extra-label  🔧#

disallow unnecessary labels

已经禁止使用 label 了

no-fallthrough  #

disallow fallthrough of case statements

switch (foo) {
  case 1:
    doSomething();
  case 2:
    doSomethingElse();
}
switch (foo) {
  case 1:
    doSomething();
    break;
  case 2:
    doSomethingElse();
}
switch (foo) {
  case 1:
  case 2:
    doSomething();
}
no-func-assign  #

disallow reassigning function declarations

function foo() {}
foo = 1;
let foo = function () {};
foo = 1;
no-global-assign  #

disallow assignments to native objects or read-only global variables

Object = null;
foo = null;
no-implicit-coercion  🔧#

disallow shorthand type conversions

Options:
["error", {
    "allow": [
        "!!"
    ]
}]
const b = ~foo.indexOf('.');
const n = +foo;
const m = 1 * foo;
const s = '' + foo;
foo += '';
const b = foo.indexOf('.') !== -1;
const n = Number(foo);
const m = Number(foo);
const s = String(foo);
foo = String(foo);

const c = !!foo;
no-implicit-globals  #

disallow variable and function declarations in the global scope

模块化之后,不会出现这种在全局作用域下定义变量的情况

no-implied-eval  #

disallow the use of eval()-like methods

setTimeout('alert("Hello World");', 1000);
setTimeout(() => {
  alert('Hello World');
}, 1000);
no-import-assign  #

disallow assigning to imported bindings

import foo from 'foo';
foo = 1;

import * as bar from 'bar';
bar.baz = 1;
import foo from 'foo';
foo.baz = 1;

import * as bar from 'bar';
bar.baz.qux = 1;
no-inline-comments  #

disallow inline comments after code

no-inner-declarations  #

disallow variable or function declarations in nested blocks

Options:["error", "both"]
if (foo) {
  function bar() {}
}
if (foo) {
  const bar = function () {};
}
no-invalid-regexp  #

disallow invalid regular expression strings in RegExp constructors

const reg1 = new RegExp('[');
const reg2 = new RegExp('.', 'z');
const reg1 = new RegExp('[a-z]');
const reg2 = new RegExp('.', 'g');
no-invalid-this  #

disallow this keywords outside of classes or class-like objects

只允许在 class 中使用 this

function foo() {
  this.a = 0;
}
class Foo {
  constructor() {
    this.a = 0;
  }
}
no-irregular-whitespace  #

disallow irregular whitespace

Options:
["error", {
    "skipStrings": true,
    "skipComments": false,
    "skipRegExps": true,
    "skipTemplates": true
}]
function foo() {
}
const foo = ' ';
const bar = / /;
const baz = ` `;
no-iterator  #

disallow the use of the __iterator__ property

__iterator__ 是一个已废弃的属性
使用 [Symbol.iterator] 替代它

Foo.prototype.__iterator__ = function () {
  return new FooIterator(this);
};
let foo = {};
foo[Symbol.iterator] = function* () {
  yield 1;
  yield 2;
  yield 3;
};
console.log([...foo]);
// [1, 2, 3]
no-label-var  #

disallow labels that share a name with a variable

已经禁止使用 label 了

no-labels  #

disallow labeled statements

loop:
    for (let i = 0; i < 5; i++) {
        if (i === 1) {
            continue loop;
        }
        console.log(i);
    }
// 0 2 3 4
for (let i = 0; i < 5; i++) {
  if (i === 1) {
    continue;
  }
  console.log(i);
}
// 0 2 3 4
no-lone-blocks  #

disallow unnecessary nested blocks

{
  foo();
}
if (foo) {
  bar();
}
no-lonely-if  🔧#

disallow if statements as the only statement in else blocks

单独的 if 可以把逻辑表达的更清楚

no-loop-func  #

disallow function declarations that contain unsafe references inside loop statements

使用 let 就已经解决了这个问题了

no-loss-of-precision  #

Disallow Number Literals That Lose Precision

const foo = 5123000000000000000000000000001;
const foo = 12345;
no-magic-numbers  #

Disallows magic numbers

no-misleading-character-class  #

disallow characters which are made with multiple code points in character class syntax

某些特殊字符很难看出差异,最好不要在正则中使用

/^[Á]$/u.test('Á'); // false
/^[A]$/u.test('A'); // true
no-multi-assign  #

disallow use of chained assignment expressions

no-multi-str  #

disallow multiline strings

const foo =
  'Line 1\
Line 2';
const foo = `Line 1
Line 2`;
no-negated-condition  #

disallow negated conditions

否定的表达式可以把逻辑表达的更清楚

no-nested-ternary  #

disallow nested ternary expressions

no-new  #

disallow new operators outside of assignments or comparisons

new 应该作为创建一个类的实例的方法,所以不能不赋值

new Foo();
const foo = new foo();
no-new-func  #

disallow new operators with the Function object

这和 eval 是等价的

const foo = new Function('a', 'b', 'return a + b');
const foo = function (a, b) {
  return a + b;
};
no-new-native-nonconstructor  #

Disallow new operators with global non-constructor functions

const foo = new Symbol('foo');
const bar = new BigInt(9007199254740991);
const foo = Symbol('foo');
const bar = BigInt(9007199254740991);
no-new-object  #

disallow Object constructors

const foo = new Object();
const foo = {};
no-new-symbol  #

disallow new operators with the Symbol object

const foo = new Symbol('foo');
const foo = Symbol('foo');
no-new-wrappers  #

disallow new operators with the String, Number, and Boolean objects

const s = new String('foo');
const n = new Number(1);
const b = new Boolean(true);
const s = String(someValue);
const n = Number(someValue);
const b = Boolean(someValue);
no-nonoctal-decimal-escape  #

Disallow \8 and \9 escape sequences in string literals

代码格式问题,最好由 Prettier 解决

no-obj-calls  #

disallow calling global object properties as functions

const foo = Math();
const bar = JSON();
const baz = Reflect();
const foo = Math.random();
const bar = JSON.parse('{}');
const baz = Reflect.get({ x: 1, y: 2 }, 'x');
no-octal  #

disallow octal literals

编译阶段就会报错了

no-octal-escape  #

disallow octal escape sequences in string literals

编译阶段就会报错了

no-param-reassign  #

disallow reassigning function parameters

function foo(bar) {
  bar = bar || '';
}
function foo(bar_) {
  bar = bar_ || '';
}
no-plusplus  #

disallow the unary operators ++ and --

no-promise-executor-return  #

Disallow returning values from Promise executor functions

new Promise((resolve, reject) => {
  if (someCondition) {
    return defaultResult;
  }
  getSomething((err, result) => {
    if (err) {
      reject(err);
    } else {
      resolve(result);
    }
  });
});
new Promise((resolve, reject) => {
  if (someCondition) {
    resolve(defaultResult);
    return;
  }
  getSomething((err, result) => {
    if (err) {
      reject(err);
    } else {
      resolve(result);
    }
  });
});
no-proto  #

disallow the use of the __proto__ property

__proto__ 是已废弃的语法

const foo = bar.__proto__;
bar.__proto__ = baz;
const foo = Object.getPrototypeOf(bar);
Object.setPrototypeOf(bar, baz);
no-prototype-builtins  #

disallow calling some Object.prototype methods directly on objects

hasOwnProperty 比较常用

no-redeclare  #

disallow variable redeclaration

禁用 var 之后,编译阶段就会报错了

no-regex-spaces  🔧#

disallow multiple spaces in regular expressions

const reg1 = /foo   bar/;
const reg2 = new RegExp('foo   bar');
const reg1 = /foo {3}bar/;
const reg2 = new RegExp('foo {3}bar');
no-restricted-exports  #

Disallow specified names in exports

no-restricted-globals  #

disallow specified global variables

no-restricted-imports  #

disallow specified modules when loaded by import

no-restricted-properties  #

disallow certain properties on certain objects

no-restricted-syntax  #

disallow specified syntax

no-return-assign  #

disallow assignment operators in return statements

Options:["error", "always"]
function foo() {
  return (bar = 1);
}
function foo() {
  bar = 1;
  return bar;
}
no-return-await  #

disallow unnecessary return await

no-script-url  #

disallow javascript: urls

有些场景下还是需要用到这个

no-self-assign  #

disallow assignments where both sides are exactly the same

foo = foo;
foo = bar;
no-self-compare  #

disallow comparisons where both sides are exactly the same

if (foo === foo) {
}
if (NaN === NaN) {
}
if (foo === bar) {
}
if (isNaN(foo)) {
}
no-sequences  #

disallow comma operators

foo = doSomething(), 1;
doSomething();
foo = 1;
no-setter-return  #

Disallow returning values from setters

const foo = {
  set bar(value) {
    this.barValue = 'bar ' + value;
    return this.barValue;
  },
};
const foo = {
  set bar(value) {
    this.barValue = 'bar ' + value;
  },
};
no-shadow  #

Disallow variable declarations from shadowing variables declared in the outer scope

很多时候函数的形参和传参是同名的

no-shadow-restricted-names  #

disallow identifiers from shadowing restricted names

const undefined = 1;
function foo(NaN) {}
function Infinity() {}
console.log(undefined);
console.log(NaN);
console.log(Infinity);
no-sparse-arrays  #

disallow sparse arrays

const foo = [1, 2, , 3];
const foo = [1, 2, 3];
no-template-curly-in-string  #

disallow template literal placeholder syntax in regular strings

const foo = 'Hello ${bar}';
const foo = 'Hello {bar}';
no-ternary  #

disallow ternary operators

no-this-before-super  #

disallow this/super before calling super() in constructors

class Foo extends Bar {
  constructor() {
    this.foo = 1;
    super();
  }
}
class Foo extends Bar {
  constructor() {
    super();
    this.foo = 1;
  }
}
no-throw-literal  #

disallow throwing literals as exceptions

throw 'foo';
throw 1;
throw new Error('foo');
no-undef  #

disallow the use of undeclared variables

foo(bar);
function foo() {}
const bar = 1;
foo(bar);

if (typeof baz === 'number') {
}
no-undef-init  🔧#

disallow initializing variables to undefined

let foo = undefined;
let foo;
no-undefined  #

disallow the use of undefined as an identifier

no-underscore-dangle  #

disallow dangling underscores in identifiers

no-unmodified-loop-condition  #

disallow unmodified loop conditions

let foo = 10;
while (foo) {
  console.log(foo);
}
let foo = 10;
while (foo) {
  console.log(foo);
  foo--;
}
no-unneeded-ternary  🔧#

disallow ternary operators when simpler alternatives exist

后者表达的更清晰

no-unreachable  #

disallow unreachable code after return, throw, continue, and break statements

function foo() {
  return;
  const bar = 1;
}
function foo() {
  return;
  // const bar = 1;
}
no-unreachable-loop  #

Disallow loops with a body that allows only one iteration

for (foo of bar) {
  if (foo.id === id) {
    doSomething(foo);
  }
  break;
}
for (foo of bar) {
  if (foo.id === id) {
    doSomething(foo);
    break;
  }
}
no-unsafe-finally  #

disallow control flow statements in finally blocks

finally 中的语句会在 try 之前执行

function foo() {
  try {
    return 1;
  } finally {
    // finally 会在 try 之前执行,故会 return 2
    return 2;
  }
}
function foo() {
  try {
    return 1;
  } finally {
    console.log(2);
  }
}
no-unsafe-negation  #

disallow negating the left operand of relational operators

if (!key in object) {
}
if (!obj instanceof SomeClass) {
}
if (!(key in object)) {
}
if (!(obj instanceof SomeClass)) {
}
no-unsafe-optional-chaining  #

disallow use of optional chaining in contexts where the undefined value is not allowed

(obj?.foo)();

(obj?.foo ?? obj?.bar)();
obj?.foo();

(obj?.foo ?? bar)();
no-unused-expressions  #

Disallow unused expressions

Options:
["error", {
    "allowShortCircuit": true,
    "allowTernary": true,
    "allowTaggedTemplates": true
}]
1;
foo;
('foo');
foo && bar;
foo || bar;
foo ? bar : baz;
`bar`;
'use strict';
foo && bar();
foo || bar();
foo ? bar() : baz();
foo`bar`;
no-unused-labels  🔧#

disallow unused labels

已经禁止使用 label 了

no-unused-private-class-members  #

disallow unused private class members

class Foo1 {
  #unusedMember = 5;
}

class Foo2 {
  #usedOnlyInWrite = 5;
  method() {
    this.#usedOnlyInWrite = 42;
  }
}

class Foo3 {
  #usedOnlyToUpdateItself = 5;
  method() {
    this.#usedOnlyToUpdateItself++;
  }
}

class Foo4 {
  #unusedMethod() {}
}

class Foo5 {
  get #unusedAccessor() {}
  set #unusedAccessor(value) {}
}
class Foo1 {
  #usedMember = 42;
  method() {
    return this.#usedMember;
  }
}

class Foo2 {
  #usedMethod() {
    return 42;
  }
  anotherMethod() {
    return this.#usedMethod();
  }
}

class Foo3 {
  get #usedAccessor() {}
  set #usedAccessor(value) {}

  method() {
    this.#usedAccessor = 42;
  }
}
no-unused-vars  #

disallow unused variables

Options:
["error", {
    "vars": "all",
    "args": "none",
    "ignoreRestSiblings": false,
    "caughtErrors": "none"
}]
let foo = 1;
foo = 2;

function bar(baz) {}

const { baz, ...rest } = data;
let foo = 1;
console.log(foo);

function bar(baz) {}
bar();

const { baz, ...rest } = data;
console.log(baz, rest);

try {
} catch (e) {}
no-use-before-define  #

disallow the use of variables before they are defined

Options:
["error", {
    "variables": false,
    "functions": false,
    "classes": false
}]
console.log(foo);
const foo = 1;

new Baz();
class Baz {}
(() => {
  console.log(foo);
})();
const foo = 1;
console.log(foo);

bar();
function bar() {}

(() => {
  new Baz();
})();
class Baz {}
new Baz();
no-useless-backreference  #

Disallow useless backreferences in regular expressions

某些回溯引用语法上没问题,但是会永远匹配到空字符串

/^(?:(a)|\1b)$/; // reference to (a) into another alternative
/^(?:(a)|(b)\2)$/; // reference to (b)
no-useless-call  #

disallow unnecessary calls to .call() and .apply()

foo.call(null, 1, 2, 3); // foo(1, 2, 3)
foo.apply(null, [1, 2, 3]); // foo(1, 2, 3)

foo.bar.call(foo, 1, 2, 3); // foo.bar(1, 2, 3);
foo.bar.apply(foo, [1, 2, 3]); // foo.bar(1, 2, 3);
foo.call(bar, 1, 2, 3);
foo.apply(bar, [1, 2, 3]);

foo.bar.call(baz, 1, 2, 3);
foo.bar.apply(baz, [1, 2, 3]);
no-useless-catch  #

disallow unnecessary catch clauses

这样的 catch 是没有意义的,等价于直接执行 try 里的代码

try {
  doSomethingThatMightThrow();
} catch (e) {
  throw e;
}
doSomethingThatMightThrow();

try {
  doSomethingThatMightThrow();
} catch (e) {
  doSomethingBeforeRethrow();
  throw e;
}
no-useless-computed-key  🔧#

disallow unnecessary computed property keys in object literals

const foo = {
  ['1']: 1,
  ['bar']: 'bar',
};
const foo = {
  1: 1,
  bar: 'bar',
};
no-useless-concat  #

disallow unnecessary concatenation of literals or template literals

const foo = 'f' + 'oo';
const bar = `b` + `ar`;
const foo = 'fo';
const bar = 1 + `ar`;
no-useless-constructor  #

disallow unnecessary constructors

class Foo {
  constructor() {}
}
class Bar extends Foo {
  constructor(...args) {
    super(...args);
  }
}
class Foo {
  constructor() {
    doSomething();
  }
}
class Bar extends Foo {
  constructor(...args) {
    super(...args);
    doSomething();
  }
}
no-useless-escape  #

disallow unnecessary escape characters

转义可以使代码更易懂

no-useless-rename  🔧#

disallow renaming import, export, and destructured assignments to the same name

import { foo as foo } from 'foo';
const bar = 1;
export { bar as bar };
let { baz: baz } = foo;
import { foo } from 'foo';
const bar = 1;
export { bar };
let { baz } = foo;
no-useless-return  🔧#

disallow redundant return statements

no-var  🔧#

require let or const instead of var

var foo = 1;
let foo = 1;
const bar = 2;
no-void  #

disallow void operators

function foo() {
  return void 0;
}
function foo() {
  return;
}
no-warning-comments  #

disallow specified warning terms in comments

no-with  #

disallow with statements

编译阶段就会报错了

object-shorthand  🔧#

require or disallow method and property shorthand syntax for object literals

有时后者可以使代码结构更清晰

one-var  🔧#

enforce variables to be declared either together or separately in functions

Options:["error", "never"]
let foo, bar;
const baz = 1,
  qux = 2;
let foo;
let bar;
const baz = 1;
const qux = 2;
operator-assignment  🔧#

require or disallow assignment operator shorthand where possible

padding-line-between-statements  #

require or disallow padding lines between statements

prefer-arrow-callback  🔧#

Require using arrow functions for callbacks

foo(function (a) {
  return a;
});
oo((a) => a);
prefer-const  🔧#

require const declarations for variables that are never reassigned after declared

prefer-destructuring  🔧#

require destructuring from arrays and/or objects

prefer-exponentiation-operator  🔧#

Disallow the use of Math.pow in favor of the ** operator

prefer-named-capture-group  #

enforce using named capture group in regular expression

正则表达式已经较难理解了,没必要强制加上命名组

prefer-numeric-literals  🔧#

disallow parseInt() and Number.parseInt() in favor of binary, octal, and hexadecimal literals

prefer-object-has-own  🔧#

disallow use of Object.prototype.hasOwnProperty.call() and prefer use of Object.hasOwn()

ES2022 的新接口,兼容性不太好

prefer-object-spread  🔧#

disallow using Object.assign with an object literal as the first argument and prefer the use of object spread instead.

const foo = Object.assign({}, bar);
const foo = { ...bar };

// 第一个参数为变量时允许使用 Object.assign
Object.assign(foo, baz);
prefer-promise-reject-errors  #

require using Error objects as Promise rejection reasons

Promise.reject('foo');

new Promise((resolve, reject) => {
  reject();
});

new Promise((resolve, reject) => {
  reject('foo');
});
Promise.reject(new Error('foo'));

new Promise((resolve, reject) => {
  reject(new Error('foo'));
});
prefer-regex-literals  #

disallow use of the RegExp constructor in favor of regular expression literals

new RegExp('abc');
new RegExp('\\.', 'g');
/abc/;
/\./g;
new RegExp(prefix + 'abc');
prefer-rest-params  #

require rest parameters instead of arguments

prefer-spread  #

require spread operators instead of .apply()

prefer-template  🔧#

require template literals instead of string concatenation

radix  #

enforce the consistent use of the radix argument when using parseInt()

const foo = parseInt('071'); // 57
const foo = parseInt('071', 10); // 71
require-atomic-updates  #

disallow assignments that can lead to race conditions due to usage of await or yield

这样会导致不符合预期的结果
https://github.com/eslint/eslint/issues/11899
在上面 issue 修复之前,关闭此规则

require-await  #

Disallow async functions which have no await expression

require-unicode-regexp  #

enforce the use of u flag on RegExp

require-yield  #

require generator functions to contain yield

function* foo() {
  return 1;
}
function* foo() {
  yield 1;
  return 2;
}
sort-imports  🔧#

enforce sorted import declarations within modules

sort-keys  #

require object keys to be sorted

sort-vars  🔧#

require variables within the same declaration block to be sorted

spaced-comment  #

enforce consistent spacing after the // or /* in a comment

Options:["error", "always"]
//foo
/*bar */
/**baz */
// foo
/* bar */
/** baz */
strict  🔧#

require or disallow strict mode directives

Options:["error", "never"]
'use strict';
function foo() {
  'use strict';
}
function foo() {}
symbol-description  #

require symbol descriptions

const foo = Symbol();
const foo = Symbol('foo');
use-isnan  #

require calls to isNaN() when checking for NaN

if (foo === NaN) {
}
if (isNaN(foo)) {
}
valid-typeof  #

enforce comparing typeof expressions against valid strings

if (typeof foo === 'numbe') {
}
if (typeof foo === 'number') {
}
vars-on-top  #

require var declarations be placed at the top of their containing scope

yoda  🔧#

require or disallow "Yoda" conditions

Options:["error", "never"]
if (1 === foo) {
}
if (foo === 1) {
}
if (1 < foo) {
}
if (1 < foo && foo < 10) {
}