Skip to Content

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 to alert, confirm, and prompt.
  • no-array-constructor: Reject Array(...) and new Array(...) constructor calls.
  • no-async-promise-executor: Reject new Promise(async (resolve, reject) => { ... }).
  • no-await-in-loop: Reject await expressions evaluated inside a loop body.
  • no-bitwise: Reject bitwise operators.
  • no-caller: Reject arguments.caller and arguments.callee, both deprecated properties forbidden in strict mode.
  • no-case-declarations: Reject lexical declarations inside case or default clauses.
  • 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 to console.*.
  • no-constant-condition: Reject conditions whose value can be determined statically.
  • no-continue: Reject continue statements.
  • no-constructor-return: Reject return X; (with a value) inside a class constructor.
  • no-control-regex: Reject ASCII control characters inside regular expression literals and RegExp strings.
  • no-debugger: Reject debugger statements.
  • no-delete-var: Reject delete applied to plain variable bindings.
  • no-dupe-args: Reject function 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: Reject if (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 same case label appearing twice in a switch, 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 an else block whose preceding if branch already terminates control flow with return, 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", and export {}.
  • no-empty-pattern: Reject empty destructuring patterns.
  • no-empty-static-block: Reject empty static {} class initialization blocks.
  • no-eq-null: Reject loose null comparisons.
  • no-eval: Reject eval(...) and indirect eval calls, almost always a security or correctness bug.
  • no-ex-assign: Reject reassigning the parameter of a catch clause.
  • no-extend-native: Reject assignments to a built-in prototype such as Array.prototype.foo = bar.
  • no-extra-bind: Reject unnecessary Function.prototype.bind() calls.
  • no-extra-boolean-cast: Reject redundant boolean casts such as !!Boolean(x), if (Boolean(x)), or Boolean(!!x).
  • no-fallthrough: Reject switch case fall-through unless preceded by an explicit // falls through comment.
  • 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 an import declaration, assignment (x = ...), compound assignment.
  • no-inner-declarations: Reject function and var declarations nested in non-function blocks , they hoist in surprising ways.
  • no-invalid-this: Reject this references 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: Reject if (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 through Number.
  • no-magic-numbers: Reject inline numeric literals outside const initializer 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 as a = b = 0.
  • no-multi-str: Reject backslash-newline multiline string literals.
  • no-negated-condition: Reject if (!cond) { ... } else { ... }, flip the branches.
  • no-nested-ternary: Reject ternary expressions nested in other ternaries.
  • no-new: Reject new expressions whose return value is not assigned or used.
  • no-new-func: Reject new Function(...) and Function(...) calls.
  • no-new-wrappers: Reject primitive wrapper constructors new String(...), new Number(...), new Boolean(...).
  • no-new-symbol: Reject new Symbol(...).
  • no-obj-calls: Reject calling global non-callable objects as functions.
  • no-object-constructor: Reject new Object() and Object() 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: Reject return inside the Promise executor function.
  • no-proto: Reject access to obj.__proto__; use Object.getPrototypeOf / Object.setPrototypeOf.
  • no-prototype-builtins: Reject obj.hasOwnProperty(key) and other direct Object.prototype builtins 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: Reject import declarations 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 of return , almost always a typo for ===.
  • no-script-url: Reject javascript: URLs in string literals, they execute their body as code on browser navigation.
  • no-self-assign: Reject x = x and destructuring forms.
  • no-self-compare: Reject comparing a value to itself.
  • no-sequences: Reject comma expressions outside the heads of for statements.
  • no-setter-return: Reject explicit return from 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: Reject this references that precede the first super() call in a derived constructor.
  • no-throw-literal: Reject throwing non-Error operands.
  • no-undef-init: Reject initializing a variable to the literal undefined , declaring.
  • no-undefined: Reject use of the global undefined identifier.
  • no-unneeded-ternary: Reject cond ? true : false and similar ternaries.
  • no-unreachable: Reject statements that follow an unconditional return, throw, break, or continue in the same block.
  • no-unsafe-finally: Reject return and throw inside a finally block.
  • no-unsafe-negation: Reject !key in obj and !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 bare x; or 'use strict' && f();.
  • no-unused-labels: Reject labels that no break or continue statement 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: Reject catch (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 bare return; whose only effect is to end a function body.
  • no-var: Reject var declarations.
  • no-with: Reject with (...) statements.

Prefer

Require

  • require-yield: Require generator functions to contain at least one yield.

Consistency

  • consistent-return: Reject functions where some return statements return a value and others do not.
  • sort-imports: Reject import specifiers within a single import declaration.
  • sort-keys: Reject object-literal property keys.

Validation

  • valid-typeof: Restrict the right-hand operand of typeof to the documented strings.

Other checks

  • curly: Require block statements for every if, else, while, for, and do body, reject the single-statement shorthand.
  • default-case: Require switch statements to include a default clause.
  • default-case-last: Require the default clause of a switch statement.
  • 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: Reject for statements whose update clause moves the counter away from the termination condition.
  • getter-return: Require a get accessor’s body to return a value on every reachable exit.
  • grouped-accessor-pairs: Require the get and set accessors of a single property.
  • guard-for-in: Require the body of every for (key in obj) loop to begin with a guard against inherited keys.
  • id-length: Reject identifier names shorter than two characters.
  • init-declarations: Require every var / let declaration.
  • 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 for parseInt(str, radix).
  • use-isnan: Require Number.isNaN / isNaN for NaN checks.
  • vars-on-top: Require var declarations to be hoisted to the top of their scope by hand, mirroring how the engine treats them.
  • yoda: Reject Yoda-style comparisons ; use if (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?: boolean

    Keep clause-level import type declarations 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 as import { type Foo } stay on the value side because the whole import clause is not type-only. Default: false.

  • includeExports?: boolean

    Also treat export … from declarations 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; }
Last updated on