Core
Generic ESLint-compatible rules that apply to both JavaScript and TypeScript source.
Every rule listed here corresponds 1-to-1 with an ESLint core rule of the same kebab-case id.
TypeScript-only rules and @typescript-eslint extension rules do not live here. They belong to TypeScript.
Keeping the core family namespace-free means projects migrating from ESLint can paste their rule severities into a ttsc.lint.config.ts file without renaming anything.
The fix availability noted in each rule’s JSDoc applies when ttsc fix or the LSP code action is invoked; a rule marked Autofixable may still produce diagnostics that require human review for edge cases.
Source: ESLint core rules (MIT).
Rule index
Each rule name links to the detailed section below.
Examples come from the checked lint corpus or package-level rule tests when project layout matters.
Disallow
no-alert: Reject calls toalert,confirm, andprompt.no-array-constructor: RejectArray(...)andnew Array(...)constructor calls.no-async-promise-executor: Rejectnew Promise(async (resolve, reject) => { ... }).no-await-in-loop: Rejectawaitexpressions evaluated inside a loop body.no-bitwise: Reject bitwise operators.no-caller: Rejectarguments.callerandarguments.callee, both deprecated properties forbidden in strict mode.no-case-declarations: Reject lexical declarations insidecaseordefaultclauses.no-class-assign: Reject reassigning a class binding.no-compare-neg-zero: Reject comparisons against-0.no-cond-assign: Reject assignment expressions inside conditions.no-console: Reject calls toconsole.*.no-constant-condition: Reject conditions whose value can be determined statically.no-continue: Rejectcontinuestatements.no-constructor-return: Rejectreturn X;(with a value) inside a class constructor.no-control-regex: Reject ASCII control characters inside regular expression literals andRegExpstrings.no-debugger: Rejectdebuggerstatements.no-delete-var: Rejectdeleteapplied to plain variable bindings.no-dupe-args: Rejectfunction f(a, a)and similar parameter lists.no-dupe-class-members: Reject two declarations of the same member on a single class.no-dupe-else-if: Rejectif (a) {} else if (a) {}, the second branch is unreachable.no-dupe-keys: Reject{ a: 1, a: 2 }, duplicate property keys in an object literal silently overwrite earlier values.no-duplicate-case: Reject the samecaselabel appearing twice in aswitch, later duplicates are unreachable.no-duplicate-imports: Reject a repeated module specifier when the import declarations could be merged into one legal declaration.no-else-return: Reject anelseblock whose precedingifbranch already terminates control flow withreturn,throw,break.no-empty: Reject empty blocks that almost always indicate forgotten code.no-empty-character-class: Reject empty regex character classes.no-empty-function: Reject empty function and method bodies.no-empty-named-blocks: Reject empty named import or export clauses,import {} from "x",import name, {} from "x", andexport {}.no-empty-pattern: Reject empty destructuring patterns.no-empty-static-block: Reject emptystatic {}class initialization blocks.no-eq-null: Reject loose null comparisons.no-eval: Rejecteval(...)and indirectevalcalls, almost always a security or correctness bug.no-ex-assign: Reject reassigning the parameter of acatchclause.no-extend-native: Reject assignments to a built-in prototype such asArray.prototype.foo = bar.no-extra-bind: Reject unnecessaryFunction.prototype.bind()calls.no-extra-boolean-cast: Reject redundant boolean casts such as!!Boolean(x),if (Boolean(x)), orBoolean(!!x).no-fallthrough: Rejectswitchcase fall-through unless preceded by an explicit// falls throughcomment.no-func-assign: Reject reassignment of function declarations.no-implicit-coercion: Reject common implicit-coercion idioms.no-import-assign: Reject writes to a binding introduced by animportdeclaration, assignment (x = ...), compound assignment.no-inner-declarations: Rejectfunctionandvardeclarations nested in non-function blocks , they hoist in surprising ways.no-invalid-this: Rejectthisreferences outside any function-like, class method, or class-static-block context.no-irregular-whitespace: Reject irregular whitespace characters in source.no-iterator: Reject the legacy__iterator__property, a SpiderMonkey-only extension predating ES2015 iterators.no-labels: Reject labeled statements.no-lone-blocks: Reject standalone{ ... }blocks that introduce no lexical scope distinct from the surrounding block.no-lonely-if: Rejectif (cond) { if (...) { ... } }.no-loop-func: Reject function declarations defined inside the body of a loop.no-loss-of-precision: Reject numeric literals whose source text cannot round-trip throughNumber.no-magic-numbers: Reject inline numeric literals outsideconstinitializer position.no-misleading-character-class: Reject regex character classes that contain combined Unicode sequences (e.g. surrogate pairs).no-mixed-operators: Reject mixing operators of different precedence families in the same expression.no-multi-assign: Reject chained assignment such asa = b = 0.no-multi-str: Reject backslash-newline multiline string literals.no-negated-condition: Rejectif (!cond) { ... } else { ... }, flip the branches.no-nested-ternary: Reject ternary expressions nested in other ternaries.no-new: Rejectnewexpressions whose return value is not assigned or used.no-new-func: Rejectnew Function(...)andFunction(...)calls.no-new-wrappers: Reject primitive wrapper constructorsnew String(...),new Number(...),new Boolean(...).no-new-symbol: Rejectnew Symbol(...).no-obj-calls: Reject calling global non-callable objects as functions.no-object-constructor: Rejectnew Object()andObject()constructor calls.no-octal: Reject legacy octal literals.no-octal-escape: Reject octal escape sequences in string literals.no-param-reassign: Reject reassigning a function parameter inside the body of the function it belongs to.no-plusplus: Reject++and--operators.no-promise-executor-return: Rejectreturninside the Promise executor function.no-proto: Reject access toobj.__proto__; useObject.getPrototypeOf/Object.setPrototypeOf.no-prototype-builtins: Rejectobj.hasOwnProperty(key)and other directObject.prototypebuiltins on user objects.no-redeclare: Reject declaring the same binding more than once in the same scope.no-regex-spaces: Reject more than one consecutive literal space in a regex.no-restricted-imports: Rejectimportdeclarations targeting any module specifier in the project denylist.no-restricted-syntax: Reject AST node kinds listed in the project denylist.no-return-assign: Reject assignment expressions used as the operand ofreturn, almost always a typo for===.no-script-url: Rejectjavascript:URLs in string literals, they execute their body as code on browser navigation.no-self-assign: Rejectx = xand destructuring forms.no-self-compare: Reject comparing a value to itself.no-sequences: Reject comma expressions outside the heads offorstatements.no-setter-return: Reject explicitreturnfrom a setter, setters’ return values are ignored.no-shadow: Reject a variable declaration that shadows a same-name binding in an enclosing scope.no-shadow-restricted-names: Reject redeclaring restricted globals.no-sparse-arrays: Reject array literals with elision.no-template-curly-in-string: Reject${expr}inside ordinary single- or double-quoted strings, almost always a missing template-literal backtick.no-this-before-super: Rejectthisreferences that precede the firstsuper()call in a derived constructor.no-throw-literal: Reject throwing non-Error operands.no-undef-init: Reject initializing a variable to the literalundefined, declaring.no-undefined: Reject use of the globalundefinedidentifier.no-unneeded-ternary: Rejectcond ? true : falseand similar ternaries.no-unreachable: Reject statements that follow an unconditionalreturn,throw,break, orcontinuein the same block.no-unsafe-finally: Rejectreturnandthrowinside afinallyblock.no-unsafe-negation: Reject!key in objand!a instanceof B.no-unsafe-optional-chaining: Reject member access or call expressions that chain off an optional chain.no-unused-expressions: Reject expression statements with no observable effect, like a barex;or'use strict' && f();.no-unused-labels: Reject labels that nobreakorcontinuestatement references.no-useless-assignment: Reject an assignment whose value is immediately overwritten by the very next statement.no-useless-call: Reject unnecessary.call()/.apply()calls.no-useless-catch: Rejectcatch (e) { throw e }patterns that only rethrow the caught error.no-useless-computed-key: Reject computed property keys whose expression is a literal identifier.no-useless-concat: Reject"a" + "b"and similar concatenations.no-useless-constructor: Reject empty constructor bodies that add nothing over the implicit constructor.no-useless-escape: Reject unnecessary escape sequences in strings and regex literals.no-useless-rename: Reject{ x: x }destructuring renames.no-useless-return: Reject a barereturn;whose only effect is to end a function body.no-var: Rejectvardeclarations.no-with: Rejectwith (...)statements.
Prefer
prefer-arrow-callback: Rejectfunction() { ... }expressions passed as callback arguments, prefer the arrow form.prefer-const: Requireconstfor variables that are never reassigned after declaration.prefer-destructuring: Reject single-property and single-index variable declarations.prefer-exponentiation-operator: Prefer the**operator overMath.pow(base, exp).prefer-for-of: Preferfor..ofover a traditionalfor (let i = 0; i < arr.length; i++)loop.prefer-object-has-own: PreferObject.hasOwn(obj, key)overObject.prototype.hasOwnProperty.call(obj, key).prefer-object-spread: Prefer object-spread{ ...a, ...b }overObject.assign({}, a, b).prefer-named-capture-group: Reject regex literals with unnamed capturing groups(...), prefer named groups(?<name>...).prefer-numeric-literals: Prefer ES2015+ numeric literal forms overparseInt(string, 2 | 8 | 16).prefer-rest-params: Reject reading fromargumentsin a non-arrow function body, prefer the ES2015 rest-parameter form(...args).prefer-spread: Prefer spread argumentsf(...args)overf.apply(null, args).prefer-template: Prefer template literals over string concatenation.
Require
require-yield: Require generator functions to contain at least oneyield.
Consistency
consistent-return: Reject functions where somereturnstatements return a value and others do not.sort-imports: Reject import specifiers within a singleimportdeclaration.sort-keys: Reject object-literal property keys.
Validation
valid-typeof: Restrict the right-hand operand oftypeofto the documented strings.
Other checks
curly: Require block statements for everyif,else,while,for, anddobody, reject the single-statement shorthand.default-case: Requireswitchstatements to include adefaultclause.default-case-last: Require thedefaultclause of aswitchstatement.camelcase: Reject identifier declarations that aren’t camelCase or PascalCase, snake_case bindings are flagged.complexity: Reject function bodies whose cyclomatic complexity exceeds twenty (default ESLint threshold).default-param-last: Reject(req, opt = 1, req2)and similar parameter lists.dot-notation: Prefer dot access over bracket access.eqeqeq: Require strict equality operators===/!==over==/!=.for-direction: Rejectforstatements whose update clause moves the counter away from the termination condition.getter-return: Require agetaccessor’s body to return a value on every reachable exit.grouped-accessor-pairs: Require thegetandsetaccessors of a single property.guard-for-in: Require the body of everyfor (key in obj)loop to begin with a guard against inherited keys.id-length: Reject identifier names shorter than two characters.init-declarations: Require everyvar/letdeclaration.max-classes-per-file: Reject a source file that declares more than one class.max-depth: Reject block-statement nesting deeper than four levels inside a function.max-lines: Reject a source file whose total line count exceeds three hundred.max-lines-per-function: Reject a function whose body spans more than fifty lines.max-nested-callbacks: Reject callback nesting deeper than ten inside a single function.max-params: Reject function declarations whose parameter list grows beyond three.max-statements: Reject function bodies whose statement count exceeds ten.object-shorthand: Reject{ foo: foo }and similar object-literal shorthand candidates.operator-assignment: Prefer compound assignment over the long form.radix: Require an explicit radix argument forparseInt(str, radix).use-isnan: RequireNumber.isNaN/isNaNforNaNchecks.vars-on-top: Requirevardeclarations to be hoisted to the top of their scope by hand, mirroring how the engine treats them.yoda: Reject Yoda-style comparisons ; useif (x === 42).
Rules
curly
Require block statements for every if, else, while, for, and do body, reject the single-statement shorthand.
Example:
const flag: boolean = Math.random() > 0.5;
// reports: curly (error)
if (flag) console.log("if");default-case
Require switch statements to include a default clause.
A switch without default silently drops every discriminant value that no case label matched.
The rule forces the catch-all branch to be written out so unhandled cases become an intentional decision instead of a hidden fall-through.
Example:
function classify(kind: string): string {
// reports: default-case (error)
switch (kind) {
case "a":
return "letter-a";
case "b":
return "letter-b";
}
return "unknown";
}default-case-last
Require the default clause of a switch statement to appear after every explicit case label.
Placing default ahead of a case reverses the visual order of the labels and changes the fall-through path, running default and then falling into the next case is almost always a misordering rather than intent.
Example:
function classify(kind: string): string {
switch (kind) {
// reports: default-case-last (error)
default:
return "unknown";
case "a":
return "letter-a";
case "b":
return "letter-b";
}
}camelcase
Reject identifier declarations that aren’t camelCase or PascalCase, snake_case bindings are flagged.
Example:
// reports: camelcase (error)
const snake_value: number = 1;
const camelValue: number = 2;
const PascalValue: number = 3;
const _private: number = 4;
const MAX_VALUE: number = 5;
function goodName(): void {}
// reports: camelcase (error)
function bad_name(): void {}
class GoodClass {}
// reports: camelcase (error)
class bad_class {}
function take(good: number, _ignored: number): void {
void good;
}complexity
Reject function bodies whose cyclomatic complexity exceeds twenty (default ESLint threshold).
Example:
// reports: complexity (error)
function tooComplex(input: number): string {
// Base complexity is 1. The body below adds 21 more branching points,
// enough to exceed ESLint's default limit of 20.
if (input === 0) return "zero";
if (input === 1) return "one";
if (input === 2) return "two";
if (input === 3) return "three";
if (input === 4) return "four";
if (input === 5) return "five";
if (input === 6) return "six";
if (input === 7) return "seven";
if (input === 8) return "eight";
if (input === 9) return "nine";
if (input === 10) return "ten";
if (input === 11) return "eleven";
if (input === 12) return "twelve";
if (input === 13) return "thirteen";
if (input === 14) return "fourteen";
if (input === 15) return "fifteen";
if (input === 16) return "sixteen";
if (input === 17) return "seventeen";
if (input === 18) return "eighteen";
if (input === 19) return "nineteen";
if (input === 20) return "twenty";
return "many";
}consistent-return
Reject functions where some return statements return a value and others (explicit bare return; or implicit fall-through) do not.
Example:
// reports: consistent-return (error)
function mixed(flag: boolean): number | undefined {
if (flag) {
return 1;
}
return;
}default-param-last
Reject (req, opt = 1, req2) and similar parameter lists where a required parameter follows an optional or default-valued one.
The call site cannot omit the trailing required parameter, so the optional becomes positionally required too, almost always an accidental ordering.
Example:
function bad(
// reports: default-param-last (error)
a?: number,
b: number,
): number {
return (a ?? 0) + b;
}
function trailing(b: number, a?: number): number {
return (a ?? 0) + b;
}dot-notation
Prefer dot access (obj.value) over bracket access (obj["value"]) when the string key is a valid JavaScript identifier.
Bracket access remains accepted for reserved words, dynamic keys, or keys containing characters that cannot appear in an identifier.
Example:
const box = { name: "ttsc", "not-valid-key": "kept" };
// reports: dot-notation (error)
const value = box["name"];
const kept = box["not-valid-key"];eqeqeq
Require strict equality operators === / !== over == / !=.
Loose equality performs implicit type coercion that frequently hides bugs.
Example:
function f(left: number | string, right: number | string) {
// reports: eqeqeq (error)
return left == right;
}for-direction
Reject for statements whose update clause moves the counter away from the termination condition, such as for (let i = 0; i < 10; i--). Such loops either never run or never terminate.
Example:
// reports: for-direction (error)
for (let i = 0; i < 10; i--) {}getter-return
Require a get accessor’s body to return a value on every reachable exit.
A getter that falls through returns undefined to the caller, which is almost never the intent and turns into a silent bug that only surfaces when the property is finally read.
Example:
class MissingReturn {
// reports: getter-return (error)
get value(): number {
const x = 1 + 1;
}
}grouped-accessor-pairs
Require the get and set accessors of a single property to be declared adjacent in the class body.
When the read and write halves of a property are split apart by unrelated members, a reader scanning the class has to chase the pair across the body, and patches to one half are easy to make without noticing the other.
Example:
class SplitAccessor {
private state = 0;
get value(): number {
return this.state;
}
other(): void {
this.state += 1;
}
// reports: grouped-accessor-pairs (error)
set value(next: number) {
this.state = next;
}
}guard-for-in
Require the body of every for (key in obj) loop to begin with a guard against inherited keys: Object.hasOwn(obj, key) or the older Object.prototype.hasOwnProperty.call(obj, key).
The inverted-guard early-skip shape if (!Object.hasOwn(...)) continue; is also accepted.
Without the guard the loop processes every enumerable name on the prototype chain, including monkey-patches someone else attached to Object.prototype, so an unguarded body silently leaks work onto inherited entries.
Example:
function dumpAll(obj: Record<string, unknown>): void {
// reports: guard-for-in (error)
for (const key in obj) {
console.log(key, obj[key]);
}
}id-length
Reject identifier names shorter than two characters.
Example:
// reports: id-length (error)
const a: number = 1;
const ab: number = 2;
const longer: number = 3;
// reports: id-length (error)
function f(): void {}
function go(): void {}
// reports: id-length (error)
class C {}
class Foo {}
function take(
// reports: id-length (error)
x: number,
yy: number,
longParam: number,
): void {
void yy;
void longParam;
}init-declarations
Require every var / let declaration to be initialized at its declaration site.
Example:
// reports: init-declarations (error)
let pending: number | undefined;
pending = 1;max-classes-per-file
Reject a source file that declares more than one class.
Example:
class First {
value(): number {
return 1;
}
}
// reports: max-classes-per-file (error)
class Second {
value(): number {
return 2;
}
}max-depth
Reject block-statement nesting deeper than four levels inside a function.
Example:
function deep(values: ReadonlyArray<number>): number {
let total = 0;
if (values.length > 0) {
for (const value of values) {
while (total < 100) {
if (value > 0) {
// reports: max-depth (error)
if (value % 2 === 0) {
total += value;
}
}
total += 1;
}
}
}
return total;
}max-lines
Reject a source file whose total line count exceeds three hundred.
Example:
void 290;
void 291;
void 292;
void 293;
void 294;
void 295;
void 296;
void 297;
void 298;
void 299;
// reports: max-lines (error)
void 301;
void 302;
void 303;
void 304;
void 305;max-lines-per-function
Reject a function whose body spans more than fifty lines.
Example:
// With max set to 10.
// reports: max-lines-per-function (error)
function longBody(): number {
let total = 0;
total += 1;
total += 1;
total += 1;
total += 1;
total += 1;
total += 1;
total += 1;
total += 1;
total += 1;
total += 1;
total += 1;
total += 1;
return total;
}max-nested-callbacks
Reject callback nesting deeper than ten inside a single function.
Example:
schedule(() =>
schedule(() =>
schedule(() =>
schedule(() =>
schedule(() =>
schedule(() =>
schedule(() =>
schedule(() =>
schedule(() =>
schedule(() =>
// reports: max-nested-callbacks (error)
schedule(() => {
void 0;
}),
),
),
),
),
),
),
),
),
),
);max-params
Reject function declarations whose parameter list grows beyond three.
Long parameter lists are hard to read at the call site because positional arguments lose their names; folding them into an options object recovers the names and lets callers pass a subset.
Every function-like declaration is checked: function declarations, function expressions, arrow functions, methods, accessors, and constructors.
The threshold is fixed at three to match the ESLint default; rule options are deferred.
Example:
// reports: max-params (error)
function four(a: number, b: number, c: number, d: number): number {
return a + b + c + d;
}max-statements
Reject function bodies whose statement count exceeds ten.
Example:
// reports: max-statements (error)
function eleven(): number {
const a = 1;
const b = 2;
const c = 3;
const d = 4;
const e = 5;
const f = 6;
const g = 7;
const h = 8;
const i = 9;
const j = 10;
return a + b + c + d + e + f + g + h + i + j;
}no-alert
Reject calls to alert, confirm, and prompt.
These browser dialogs block the main thread and are almost always debugging leftovers or placeholders for a proper UI component.
Example:
// reports: no-alert (error)
alert("hi");no-array-constructor
Reject Array(...) and new Array(...) constructor calls in favor of array literals.
Array(n) and [n] behave differently for a single numeric argument, and the array literal is uniformly clearer.
Example:
// reports: no-array-constructor (error)
const a = new Array();no-async-promise-executor
Reject new Promise(async (resolve, reject) => { ... }).
Promises thrown asynchronously inside the executor are dropped silently because the constructor has already returned the outer Promise. Use a regular function and call reject explicitly.
Example:
// reports: no-async-promise-executor (error)
new Promise(async (resolve) => {
resolve(1);
});no-await-in-loop
Reject await expressions evaluated inside a loop body.
The loop runs strictly serially because each iteration blocks on the previous one’s microtask hop; when the operations are independent the equivalent Promise.all([...]) is dramatically faster.
The rule intentionally exempts for await ... of because the awaitable iterator is the loop’s whole reason for existing.
Example:
async function inForLoop(): Promise<number> {
let total = 0;
for (let i = 0; i < 3; i++) {
// reports: no-await-in-loop (error)
total += await getPromise();
}
return total;
}no-bitwise
Reject bitwise operators (&, |, ^, ~, <<, >>, >>>).
Bitwise operators are almost always typos for the logical operators (&&, ||); enable when the codebase has no legitimate bit-twiddling.
Example:
function f(a: number, b: number) {
// reports: no-bitwise (error)
return a & b;
}no-caller
Reject arguments.caller and arguments.callee, both deprecated properties forbidden in strict mode.
They defeat engine optimizations and break under ES modules, where strict mode is implicit.
Example:
function f() {
// reports: no-caller (error)
return arguments.callee;
}no-case-declarations
Reject lexical declarations (let, const, class, function) inside case or default clauses without their own block, since the declaration shares the whole switch scope and leaks into sibling clauses.
Wrap the case body in { ... } to introduce a fresh block.
Example:
function f(x: number) {
switch (x) {
case 1:
// reports: no-case-declarations (error)
let y = 1;
return y;
}
return 0;
}no-class-assign
Reject reassigning a class binding (class C {}; C = ...).
The declaration name is effectively final; overwriting it silently leaves other call sites pointing at the original class.
Example:
class A {}
// reports: no-class-assign (error)
A = class Replacement {};no-compare-neg-zero
Reject comparisons against -0 (x === -0, x < -0, etc.).
=== treats +0 and -0 as equal, so the comparison never distinguishes them; use Object.is(x, -0) when the sign of zero actually matters.
Example:
function f(x: number) {
// reports: no-compare-neg-zero (error)
return x === -0;
}no-cond-assign
Reject assignment expressions inside conditions, such as if (x = y), almost always a typo for == / ===.
Example:
let a = 0;
let b = 1;
// reports: no-cond-assign (error)
if ((a = b)) {
console.log(a);
}no-console
Reject calls to console.*.
Typically configured as "warning" so leftover logging stays visible without breaking the build.
Example:
// reports: no-console (error)
console.log("hi");no-constant-condition
Reject conditions whose value can be determined statically, such as while (true) or if (false), in if, while, do/while, for, and ternary expressions.
The default checkLoops configuration still permits intentional infinite loops in a few forms; see upstream for the matrix.
Example:
// reports: no-constant-condition (error)
if (1) {
console.log("always");
}no-continue
Reject continue statements.
Stylistic policy preferring early returns or restructured loops over continue.
Example:
for (let i = 0; i < 3; i++) {
// reports: no-continue (error)
if (i === 1) continue;
console.log(i);
}no-constructor-return
Reject return X; (with a value) inside a class constructor.
The returned value is ignored when the constructor is invoked with new unless it happens to be an object; relying on that behavior is always a misunderstanding of the constructor protocol.
Example:
class Returning {
value: number;
constructor(initial: number) {
this.value = initial;
// reports: no-constructor-return (error)
return { handled: true };
}
}no-control-regex
Reject ASCII control characters (\x00-\x1F) inside regular expression literals and RegExp strings.
They render invisibly in source and almost always indicate an accidental paste or a missed \t / \n escape.
Example:
// reports: no-control-regex (error)
const r = /\x1f/;no-debugger
Reject debugger statements.
Typically configured as "error" so accidental debugger leftovers fail CI.
Example:
function f(): void {
// reports: no-debugger (error)
debugger;
}
f();no-delete-var
Reject delete applied to plain variable bindings (delete x).
The operation is forbidden in strict mode (and therefore in ES modules) and never has the intended effect on let / const / var declarations.
Example:
let value = 1;
// reports: no-delete-var (error)
delete value;no-dupe-args
Reject function f(a, a) and similar parameter lists that declare the same name twice.
The function cannot bind both arguments and fails in strict mode.
Example:
// reports: no-dupe-args (error)
function f(a: number, b: number, a: number) {
return a + b;
}
f(1, 2, 3);no-dupe-class-members
Reject two declarations of the same member on a single class. The later declaration silently overwrites the earlier one at runtime; the syntax permits it but the result is never what the author intended.
A getter and a setter for the same property coexist; an instance member and a static member with the same name coexist.
Example:
class Methods {
run(): number {
return 1;
}
// reports: no-dupe-class-members (error)
run(): number {
return 2;
}
}no-dupe-else-if
Reject if (a) {} else if (a) {}, the second branch is unreachable because the first condition already handled it.
Example:
function chooseCacheMode(isReady: boolean, isCached: boolean) {
if (isReady) {
return "ready";
} else if (isCached) {
return "cached";
}
// reports: no-dupe-else-if (error)
else if (isReady) {
return "still-ready";
}
return "cold";
}no-dupe-keys
Reject { a: 1, a: 2 }, duplicate property keys in an object literal silently overwrite earlier values.
Example:
const o = {
a: 1,
// reports: no-dupe-keys (error)
a: 2,
};no-duplicate-case
Reject the same case label appearing twice in a switch, later duplicates are unreachable.
Example:
function f(x: number) {
switch (x) {
case 1:
return "a";
// reports: no-duplicate-case (error)
case 1:
return "b";
}
return "";
}no-duplicate-imports
Reject an import declaration whose module specifier already appeared above when the two declarations could be merged into one legal declaration. Same-module pairs TypeScript cannot consolidate, such as named next to namespace bindings or a type-only default next to type-only named bindings, are not duplicates.
Options:
-
allowSeparateTypeImports?: booleanKeep clause-level
import typedeclarations out of the comparison with value imports of the same module, so one runtime import plus one type-only import may coexist. Inline type specifiers such asimport { type Foo }stay on the value side because the whole import clause is not type-only. Default:false. -
includeExports?: booleanAlso treat
export … fromdeclarations of an already imported or re-exported module as duplicates when the declarations could be merged. Default:false.
Example:
import { first } from "some-module";
// reports: no-duplicate-imports (error)
import { second } from "some-module";
// Not duplicates: named and namespace bindings cannot share one declaration.
import { named } from "unmergeable-namespace";
import * as namespace from "unmergeable-namespace";no-else-return
Reject an else block whose preceding if branch already terminates control flow with return, throw, break, or continue, flatten the body into the surrounding scope.
Example:
function describe(kind: string): string {
if (kind === "a") {
return "letter-a";
// reports: no-else-return (error)
} else {
return "other";
}
}no-empty
Reject empty blocks (if (x) {}, while (x) {}, try {} catch (e) {} etc.) that almost always indicate forgotten code.
Example:
function f(x: number) {
// reports: no-empty (error)
if (x === 0) {
}
}no-empty-character-class
Reject empty regex character classes ([]).
An empty class never matches anything, so the entire pattern can never succeed; the negated form [^] (matches any character) is allowed.
Example:
// reports: no-empty-character-class (error)
const r = /[]/;no-empty-function
Reject empty function and method bodies (function f() {}, () => {}).
Use () => undefined or a leading TODO comment when the empty body is intentional.
Example:
// reports: no-empty-function (error)
function f(): void {}
f();no-empty-named-blocks
Reject empty named import or export clauses, import {} from "x", import name, {} from "x", and export {}, which bind nothing.
The empty-only import shape leaves just the side-effect load and is better written as import "x"; the default-plus-empty form should drop the empty clause.
And a bare export {} either restates module-ness redundantly or marks an otherwise non-module file in a way that has cleaner alternatives.
The stricter sibling rule typescript/no-useless-empty-export fires only when another module-syntax statement is already present.
Example:
// reports: no-empty-named-blocks (error)
import "x";no-empty-pattern
Reject empty destructuring patterns (const {} = obj, function f([]) {}), which bind nothing and are usually mid-edit typos.
Example:
// reports: no-empty-pattern (error)
function f({}: { a?: number }): void {}
f({ a: 1 });no-empty-static-block
Reject empty static {} class initialization blocks.
Example:
class Holder {
// reports: no-empty-static-block (error)
static {}
}no-eq-null
Reject loose null comparisons (x == null).
Use x === null or the explicit x === null || x === undefined.
Pairs with eqeqeq but kept separate so the loose null shortcut can be allowed under "smart"-style eqeqeq exceptions.
Example:
function f(value: string | null) {
// reports: no-eq-null (error)
return value == null;
}no-eval
Reject eval(...) and indirect eval calls, almost always a security or correctness bug.
Example:
// reports: no-eval (error)
eval("1");no-ex-assign
Reject reassigning the parameter of a catch clause (catch (e) { e = ... }), which loses the original error reference.
Example:
try {
throw new Error("x");
} catch (e) {
// reports: no-ex-assign (error)
e = "boom";
console.log(e);
}no-extend-native
Reject assignments to a built-in prototype such as Array.prototype.foo = bar. Only <Builtin>.prototype.<key> = ... is flagged; assigning to Object.foo = ... (a static property) is left alone.
Example:
// reports: no-extend-native (error)
Array.prototype.firstItem = 1;
// reports: no-extend-native (error)
String.prototype.upper = function (): void {};
Object.debugLabel = 1;no-extra-bind
Reject unnecessary Function.prototype.bind() calls, for example, binding without arguments or binding an arrow function (which ignores this).
Example:
// reports: no-extra-bind (error)
const f = (() => 1).bind({});no-extra-boolean-cast
Reject redundant boolean casts such as !!Boolean(x), if (Boolean(x)), or Boolean(!!x).
Example:
function f(isReady: boolean) {
// reports: no-extra-boolean-cast (error)
if (!!isReady) {
return 1;
}
return 0;
}no-fallthrough
Reject switch case fall-through unless preceded by an explicit // falls through comment.
Example:
function f(x: number) {
switch (x) {
case 1:
console.log("one");
// reports: no-fallthrough (error)
case 2:
console.log("two");
break;
}
}no-func-assign
Reject reassignment of function declarations (function f() {}; f = 0;).
The hoisted binding looks final to most readers; overwriting it makes the original implementation unreachable from other references.
Example:
function g() {
return 1;
}
// reports: no-func-assign (error)
g = function () {
return 2;
};no-implicit-coercion
Reject common implicit-coercion idioms (!!x, +x, "" + x) in favor of the explicit Boolean(x) / Number(x) / String(x) conversions.
The explicit forms are more readable and avoid surprise around primitive edge cases.
Example:
const value: unknown = "ready";
// reports: no-implicit-coercion (error)
const asBool = !!value;no-import-assign
Reject writes to a binding introduced by an import declaration, assignment (x = ...), compound assignment, or increment/decrement of an imported name, plus property mutations of a namespace import (ns.foo = ...).
Imported bindings are read-only at runtime; mutating them either throws under strict mode or silently desynchronises the module’s view of its own exports.
Example:
import { x } from "y";
// reports: no-import-assign (error)
x = 5;no-inner-declarations
Reject function and var declarations nested in non-function blocks (loops, if, etc.), they hoist in surprising ways.
Example:
function outer() {
if (1) {
// reports: no-inner-declarations (error)
function inner() {}
inner();
}
}
outer();no-invalid-this
Reject this references outside any function-like, class method, or class-static-block context.
Example:
// reports: no-invalid-this (error)
const value = this;no-irregular-whitespace
Reject irregular whitespace characters (zero-width space, non-breaking space, etc.) in source, typically copy-paste artifacts from rich-text editors.
Example:
// reports: no-irregular-whitespace (error)
const a = 1;no-iterator
Reject the legacy __iterator__ property, a SpiderMonkey-only extension predating ES2015 iterators.
Use Symbol.iterator or a generator.
Example:
const legacyObject = {};
// reports: no-iterator (error)
legacyObject.__iterator__ = function* () {};no-labels
Reject labeled statements (outer: for (...) { break outer; }).
Labels obscure control flow; prefer extracting the inner loop into a function and using return, or refactoring with a flag variable.
Example:
// reports: no-labels (error)
outer: for (let i = 0; i < 3; i++) {
break outer;
}no-lone-blocks
Reject standalone { ... } blocks that introduce no lexical scope distinct from the surrounding block.
Blocks that actually declare let, const, class, or function (in strict mode) are exempt, since those declarations need the inner scope.
Example:
// reports: no-lone-blocks (error)
{
console.log("hi");
}no-lonely-if
Reject if (cond) { if (...) { ... } } where the inner if is the only statement in an else, prefer else if.
Example:
function chooseMode(isPrimary: boolean, isFallback: boolean) {
if (isPrimary) {
return "primary";
} else {
// reports: no-lonely-if (error)
if (isFallback) {
return "fallback";
}
}
return "none";
}no-loop-func
Reject function declarations defined inside the body of a loop.
Each iteration of the loop allocates a fresh function whose closure captures the surrounding let/var binding, a class of bugs where every captured function reads the iteration’s final value instead of its own.
Example:
function inForLoop(): void {
for (let i = 0; i < 3; i++) {
// reports: no-loop-func (error)
function inner() {
return i;
}
inner();
}
}no-loss-of-precision
Reject numeric literals whose source text cannot round-trip through Number without losing digits, including overflow.
Example:
// reports: no-loss-of-precision (error)
const big = 9007199254740993;no-magic-numbers
Reject inline numeric literals outside const initializer position. 0, 1, -1, array indices, and enum values are exempt.
Example:
const items = [zero, one];
const first = items[0];
// reports: no-magic-numbers (error)
const total = SECONDS_PER_MINUTE * 60;no-misleading-character-class
Reject regex character classes that contain combined Unicode sequences (e.g. surrogate pairs) which most readers will not realize represent multiple code units.
Example:
// reports: no-misleading-character-class (error)
const r = /[👍]/;no-mixed-operators
Reject mixing operators of different precedence families in the same expression without explicit parentheses around the inner sub-expression.
The famous case is a && b || c: readers expect left-to-right grouping but the parser sees (a && b) || c because && binds tighter than ||.
The conservative baseline only flags the highest-confusion mixes, logical mixed with a different logical (&& next to || / ??), and bitwise (&, |, ^) next to a comparison or logical.
Wrapping the inner sub-expression in parens suppresses the report.
Example:
// reports: no-mixed-operators (error)
const m1 = (a && b) || c;no-multi-assign
Reject chained assignment such as a = b = 0, which obscures intent and surprises readers who expect comparison.
Example:
let left: number;
let right: number;
// reports: no-multi-assign (error)
left = right = 1;no-multi-str
Reject backslash-newline multiline string literals; use template literals instead.
Example:
const s: string =
// reports: no-multi-str (error)
"line1 \
line2";no-negated-condition
Reject if (!cond) { ... } else { ... }, flip the branches so the positive condition reads first.
Example:
function f(isReady: boolean) {
// reports: no-negated-condition (error)
if (!isReady) {
return 1;
} else {
return 2;
}
}no-nested-ternary
Reject ternary expressions nested in other ternaries (a ? b : c ? d : e), which are hard to read at a glance.
Example:
function label(value: number): string {
// reports: no-nested-ternary (error)
return value === 0 ? "zero" : value > 0 ? "positive" : "negative";
}no-new
Reject new expressions whose return value is not assigned or used, the object is created only for its constructor side effects.
Example:
class Thing {}
// reports: no-new (error)
new Thing();no-new-func
Reject new Function(...) and Function(...) calls, which effectively evaluate a string and have the same risks as eval.
Example:
// reports: no-new-func (error)
const f = new Function("a", "return a");no-new-wrappers
Reject primitive wrapper constructors new String(...), new Number(...), new Boolean(...).
The resulting objects compare unequal to their primitive counterparts.
Example:
// reports: no-new-wrappers (error)
const s = new String("a");no-new-symbol
Reject new Symbol(...). Symbol is a function but not a constructor; calling it with new throws a TypeError at runtime.
The upstream rule was renamed no-new-native-nonconstructor; the legacy name remains the more readable pointer for this specific Symbol check.
Example:
// reports: no-new-symbol (error)
const bad = new Symbol("desc");no-obj-calls
Reject calling global non-callable objects as functions, such as Math() or JSON().
Example:
// reports: no-obj-calls (error)
Math();no-object-constructor
Reject new Object() and Object() constructor calls; use an object literal {} instead.
Example:
// reports: no-object-constructor (error)
const o = new Object();no-octal
Reject legacy octal literals (0123).
Use the 0o123 prefix when an octal literal is actually intended.
Example:
// reports: no-octal (error)
const n = 010;no-octal-escape
Reject octal escape sequences in string literals ("\251", "\07").
Deprecated and forbidden in strict mode; use Unicode (©) or hex (\xA9) escapes.
Example:
// reports: no-octal-escape (error)
const s: string = "\251";no-param-reassign
Reject reassigning a function parameter inside the body of the function it belongs to. The parameter name stops pointing at the caller’s argument after the write. Property mutations (param.foo = ...) are not flagged.
Example:
function reassignSimple(x: number): number {
// reports: no-param-reassign (error)
x = 1;
return x;
}no-plusplus
Reject ++ and -- operators.
Prefer += 1 / -= 1 to keep statements expression-only and avoid ASI surprises.
Example:
let i = 0;
// reports: no-plusplus (error)
i++;no-promise-executor-return
Reject return inside the Promise executor function, the value is ignored.
Example:
// reports: no-promise-executor-return (error)
new Promise((resolve) => resolve(1));no-proto
Reject access to obj.__proto__; use Object.getPrototypeOf / Object.setPrototypeOf.
Example:
const legacyObject = {};
// reports: no-proto (error)
const prototype = legacyObject.__proto__;no-prototype-builtins
Reject obj.hasOwnProperty(key) and other direct Object.prototype builtins on user objects, since the property may be shadowed.
Use Object.prototype.hasOwnProperty.call(obj, key) or Object.hasOwn.
Example:
const user = { id: 1 };
// reports: no-prototype-builtins (error)
user.hasOwnProperty("id");no-redeclare
Reject declaring the same binding more than once in the same scope (var x = 1; var x = 2;, two function foo() declarations side by side, or a parameter rebound by a later var in the body).
The second declaration silently overwrites the first; shadowing the binding in a nested scope is left alone.
Example:
var sample: number = 1;
// reports: no-redeclare (error)
var sample: number = 2;no-regex-spaces
Reject more than one consecutive literal space in a regex; use {N} quantifiers for clarity.
Example:
// reports: no-regex-spaces (error)
const r = /a b/;no-restricted-imports
Reject import declarations targeting any module specifier in the project denylist.
Example:
// reports: no-restricted-imports (error)
import _ from "lodash";no-restricted-syntax
Reject AST node kinds listed in the project denylist.
Example:
function runWith(target: { value: number }): number {
let total = 0;
// reports: no-restricted-syntax (error)
with (target) {
total = value;
}
return total;
}no-return-assign
Reject assignment expressions used as the operand of return (return x = 1), almost always a typo for ===.
Example:
let count = 0;
function f() {
// reports: no-return-assign (error)
return (count = 1);
}no-script-url
Reject javascript: URLs in string literals, they execute their body as code on browser navigation, and security scanners treat them as an eval equivalent.
Example:
// reports: no-script-url (error)
const u: string = "javascript:alert(1)";no-self-assign
Reject x = x and destructuring forms that copy a value to itself, almost always a typo.
Example:
let x = 1;
console.log(x);
// reports: no-self-assign (error)
x = x;
console.log(x);no-self-compare
Reject comparing a value to itself (x === x). Use Number.isNaN(x) to test for NaN.
Example:
function f(a: number) {
// reports: no-self-compare (error)
return a === a;
}no-sequences
Reject comma expressions (a, b) outside the heads of for statements.
Example:
function f(index: number) {
// reports: no-sequences (error)
return (index++, index);
}no-setter-return
Reject explicit return from a setter, setters’ return values are ignored.
Example:
class Holder {
set value(input: string) {
// reports: no-setter-return (error)
return "ignored";
}
}no-shadow
Reject a variable declaration that shadows a same-name binding in an enclosing scope.
Example:
let outer: number = 1;
function f(): number {
// reports: no-shadow (error)
let outer: number = 2;
return outer;
}no-shadow-restricted-names
Reject redeclaring restricted globals (NaN, Infinity, undefined, etc.).
Example:
// reports: no-shadow-restricted-names (error)
function f(undefined: number) {
return undefined;
}
f(1);no-sparse-arrays
Reject array literals with elision ([, 1, , 3]), which read surprisingly and rarely express intent.
Example:
// reports: no-sparse-arrays (error)
const a = [1, , 3];no-template-curly-in-string
Reject ${expr} inside ordinary single- or double-quoted strings, almost always a missing template-literal backtick.
Example:
// reports: no-template-curly-in-string (error)
const s: string = "hello ${name}";no-this-before-super
Reject this (or super.x) references that precede the first super() call in a derived constructor.
The runtime throws a ReferenceError on the first such access; catching it at lint time avoids a class of bugs that only surface after the constructor is actually called.
Example:
class UsesThisFirst extends Base {
constructor() {
// reports: no-this-before-super (error)
this.value = 1;
super(0);
}
}no-throw-literal
Reject throwing non-Error operands (throw "boom", throw 1).
Example:
function f() {
// reports: no-throw-literal (error)
throw "literal";
}no-undef-init
Reject initializing a variable to the literal undefined (let x = undefined), declaring without an initializer has the same effect.
Example:
// reports: no-undef-init (error)
let value = undefined;no-undefined
Reject use of the global undefined identifier; use the void 0 expression or omit the value.
Example:
// reports: no-undefined (error)
const x = undefined;no-unneeded-ternary
Reject cond ? true : false and similar ternaries that can be simplified to a boolean coercion or the condition itself.
Example:
function f(isReady: boolean) {
// reports: no-unneeded-ternary (error)
return isReady ? true : false;
}no-unreachable
Reject statements that follow an unconditional return, throw, break, or continue in the same block, control flow has already left the block, so any later statement is dead code.
The conservative baseline scans the immediate statement list of a block (or the top-level source / module body) only.
Hoistable function declarations following the terminator are exempt because they are hoisted above the unreachable point.
Example:
function afterReturn(): number {
return 1;
// reports: no-unreachable (error)
console.log("dead");
}no-unsafe-finally
Reject return and throw inside a finally block, which override any earlier return/throw from the corresponding try/catch.
Example:
function f() {
try {
throw new Error("x");
} finally {
// reports: no-unsafe-finally (error)
return 1;
}
}no-unsafe-negation
Reject !key in obj and !a instanceof B where the ! binds tighter than the relational operator and silently coerces the left operand to a boolean.
Wrap in parens (!(key in obj)) when the negation is genuinely intended.
Example:
function hasUnsafeNegation(key: string, object: Record<string, unknown>) {
// reports: no-unsafe-negation (error)
return !key in object;
}no-unsafe-optional-chaining
Reject member access or call expressions that chain off an optional chain without continuing the chain. (obj?.foo).bar throws a TypeError if obj is null/undefined; the chain must continue with ?. to remain safe.
Example:
const obj: { profile?: { name: string } } | undefined = {};
// reports: no-unsafe-optional-chaining (error)
const name = (obj?.profile).name;no-unused-expressions
Reject expression statements with no observable effect, like a bare x; or 'use strict' && f();.
Example:
function f(isReady: boolean, isCached: boolean): void {
// reports: no-unused-expressions (error)
(isReady, isCached);
}
f(true, false);no-unused-labels
Reject labels that no break or continue statement references.
Usually the targeted statement was renamed or removed but the label was left behind.
Example:
// reports: no-unused-labels (error)
unused: {
}no-useless-assignment
Reject an assignment whose value is immediately overwritten by the very next statement without an intervening read of the same identifier.
The conservative baseline only fires on two syntactically adjacent x = <expr>; statements where the left-hand sides are the same bare identifier and the second statement’s right-hand side does not reference x itself.
Almost always a leftover from refactoring.
Example:
function deadStore(): number {
let x = 0;
// reports: no-useless-assignment (error)
x = 1;
x = 2;
return x;
}no-useless-call
Reject unnecessary .call() / .apply() calls (such as f.call(undefined, x)).
Example:
function f() {}
// reports: no-useless-call (error)
f.call(undefined, 1);no-useless-catch
Reject catch (e) { throw e } patterns that only rethrow the caught error without adding context or handling.
Example:
function f() {
try {
return 1;
// reports: no-useless-catch (error)
} catch (e) {
throw e;
}
}no-useless-computed-key
Reject computed property keys whose expression is a literal identifier ({ ["foo"]: 1 }).
Example:
// reports: no-useless-computed-key (error)
const user = { ["displayName"]: "Ada" };no-useless-concat
Reject "a" + "b" and similar concatenations where every operand is a literal string.
Example:
// reports: no-useless-concat (error)
const s = "a" + "b";no-useless-constructor
Reject empty constructor bodies (class X { constructor() {} }) that add nothing over the implicit constructor.
Example:
class Empty {
// reports: no-useless-constructor (error)
constructor() {}
}no-useless-escape
Reject unnecessary escape sequences in strings and regex literals, such as "\." or /\,/. Autofixable.
Example:
// reports: no-useless-escape (error)
const value = "ab\cdef";no-useless-rename
Reject { x: x } destructuring renames that bind back to the same name. Autofixable.
Example:
const user = { displayName: "Ada" };
// reports: no-useless-rename (error)
const { displayName: displayName } = user;no-useless-return
Reject a bare return; whose only effect is to end a function body that would have returned anyway.
The conservative baseline only fires on the last statement of a function-like’s immediate body, earlier return; inside a branch or loop may still be load-bearing.
Example:
function trailing(): void {
console.log("work");
// reports: no-useless-return (error)
return;
}no-var
Reject var declarations.
Use let for mutable bindings and const for immutable ones. Autofixable to let.
Every var declaration list reports, whether it appears as a statement or directly in a for, for...in, or for...of header.
The fix only fires when the rewrite cannot change behavior, mirroring ESLint’s no-var fix conditions: the name binds exactly once in the file, is never read before the declaration or inside its own initializer, every reference stays inside the declaring block scope (a var declared in a block but read after it would stop compiling as let; a loop-header var read after its loop likewise), a loop var — declared in the body or in the header itself — is not captured by a function or arrow created inside the loop (those closures share one var binding but would capture a fresh per-iteration let binding), and the declaration does not sit under a with statement. A for...in/for...of header additionally declines when its declarator carries an Annex-B initializer (for (var i = 0 in o), a SyntaxError under let) or when the head expression reads the loop variable (for (var x of x), a TDZ ReferenceError under let). Anything else reports without a fix.
Example:
// reports: no-var (error)
var legacy = 1;
// reports: no-var (error)
for (var index = 0; index < 1; index += 1) {
JSON.stringify(index);
}no-with
Reject with (...) statements.
with is forbidden in strict mode (and therefore in modules), defeats lexical scoping, and blocks engine optimization.
Example:
function f(scope: Record<string, unknown>) {
// reports: no-with (error)
with (scope) {
console.log("hi");
}
}object-shorthand
Reject { foo: foo } and similar object-literal shorthand candidates in favor of { foo }. Autofixable.
Example:
const x = 1;
// reports: object-shorthand (error)
const o = { x: x };operator-assignment
Prefer compound assignment (x += y) over the long form (x = x + y) where the two are equivalent.
Example:
let x = 1;
console.log(x);
// reports: operator-assignment (error)
x = x + 1;
console.log(x);prefer-arrow-callback
Reject function() { ... } expressions passed as callback arguments, prefer the arrow form.
Example:
const list: readonly number[] = [1, 2, 3];
list.map(
// reports: prefer-arrow-callback (error)
function (n: number) {
return n * 2;
},
);prefer-const
Require const for variables that are never reassigned after declaration. Autofixable for single-declaration lets.
Example:
// reports: prefer-const (error)
let stable = 1;
let changing = 1;
changing = 2;prefer-destructuring
Reject single-property and single-index variable declarations (const a = obj.a, const x = arr[0]) that destructuring would replace verbatim.
Example:
const obj = { a: 1, b: 2 };
// reports: prefer-destructuring (error)
const a = obj.a;prefer-exponentiation-operator
Prefer the ** operator over Math.pow(base, exp).
Example:
// reports: prefer-exponentiation-operator (error)
const a = Math.pow(2, 3);prefer-for-of
Prefer for..of over a traditional for (let i = 0; i < arr.length; i++) loop when the index is never used inside the body.
Example:
const arr: number[] = [1, 2, 3];
// reports: prefer-for-of (error)
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}prefer-object-has-own
Prefer Object.hasOwn(obj, key) over Object.prototype.hasOwnProperty.call(obj, key). The new helper is shorter, less error-prone, and matches the form linters elsewhere recommend.
Example:
const target = { x: 1 };
// reports: prefer-object-has-own (error)
const a = Object.prototype.hasOwnProperty.call(target, "x");prefer-object-spread
Prefer object-spread { ...a, ...b } over Object.assign({}, a, b).
Only fires when the first argument is an empty object literal, mutating Object.assign(target, ...) calls are left alone because the spread form does not preserve their observable side effects.
Example:
const source = { x: 1 };
// reports: prefer-object-spread (error)
const merged = Object.assign({}, source);prefer-named-capture-group
Reject regex literals with unnamed capturing groups (...), prefer named groups (?<name>...).
Example:
// reports: prefer-named-capture-group (error)
const yearOnly = /(\d{4})/;prefer-numeric-literals
Prefer ES2015+ numeric literal forms (0b..., 0o..., 0x...) over parseInt(string, 2 | 8 | 16). The literal form is shorter, type- safe at lint time, and not subject to runtime radix mismatches.
Example:
// reports: prefer-numeric-literals (error)
const bin = parseInt("11", 2);prefer-rest-params
Reject reading from arguments in a non-arrow function body, prefer the ES2015 rest-parameter form (...args), which declares the variadic contract on the signature and yields a real array.
Example:
function sumLegacy() {
// reports: prefer-rest-params (error)
return Array.prototype.slice
.call(arguments)
.reduce((a: number, b: number) => a + b, 0);
}prefer-spread
Prefer spread arguments f(...args) over f.apply(null, args).
Only flags apply calls whose this argument is provably the same receiver (or null / undefined); calls that genuinely rebind this are left alone.
Example:
function f(a: number, b: number) {
return a + b;
}
const args: [number, number] = [1, 2];
// reports: prefer-spread (error)
f.apply(null, args);prefer-template
Prefer template literals over string concatenation when any operand is non-literal.
Example:
const name = "world";
// reports: prefer-template (error)
const s = "hi " + name + "!";radix
Require an explicit radix argument for parseInt(str, radix).
Without it, "0123" parses as decimal or octal depending on the engine.
Example:
// reports: radix (error)
const n = parseInt("42");require-yield
Require generator functions to contain at least one yield. A yield-less generator is almost always a typo.
Example:
// reports: require-yield (error)
function* gen() {
return 1;
}sort-imports
Reject import specifiers within a single import declaration that aren’t alphabetically sorted.
Example:
// reports: sort-imports (error)
import { a, b } from "first";sort-keys
Reject object-literal property keys that aren’t alphabetically sorted.
Example:
const unsorted = {
b: 1,
// reports: sort-keys (error)
a: 2,
};use-isnan
Require Number.isNaN / isNaN for NaN checks; restrict typeof comparisons to the documented strings.
Example:
function f(x: number) {
// reports: use-isnan (error)
return x === NaN;
}valid-typeof
Restrict the right-hand operand of typeof to the documented strings ("number", "object", …) so typeof x === "undefiend" typos are caught.
Example:
function f(value: unknown) {
// reports: valid-typeof (error)
return typeof value === "stirng";
}vars-on-top
Require var declarations to be hoisted to the top of their scope by hand, mirroring how the engine treats them.
Has no effect when no-var forbids var altogether.
Example:
function f() {
console.log("hi");
// reports: vars-on-top (error)
var a = 1;
}
f();yoda
Reject Yoda-style comparisons (if (42 === x)); use if (x === 42) so the variable comes first.
Example:
function f(x: number) {
// reports: yoda (error)
return 1 === x;
}