☂️ Proposed lint rules #3357
Replies: 7 comments 11 replies
-
Beta Was this translation helpful? Give feedback.
-
There's also an opportunity to make the |
Beta Was this translation helpful? Give feedback.
-
I'd consider that rule to be at least equally important to the already implemented |
Beta Was this translation helpful? Give feedback.
-
What about no-restricted-syntax? It will allow people to write their own simple rules which is nice. BTW. Are there other ways how to do custom rules? |
Beta Was this translation helpful? Give feedback.
-
interface MyObject { one: { two: string; } } |
Beta Was this translation helpful? Give feedback.
-
Unicorn has some great rules too |
Beta Was this translation helpful? Give feedback.
-
Would also like to propose no-floating-promises. Without TS compiler support for this, we've found it a very easy trap in our Jest suites to be misled into thinking they're passing when really they just ran to the end 😊 |
Beta Was this translation helpful? Give feedback.
-
ESLint
Disallow functions that exceed a given complexity score.
noInvalidConstructorSuper
Verify
super()
is called in constructors of derived classes, and not called in constructor of non-derived classes (this rule also tries to check if theextends
reference is a valid class but this is better left to a typechecker)Example errors:
class A extends B { constructor() {} }
class A { constructor() { super(); } }
Enforce default switch clause to be last.
Enforce default function parameters and optional function parameters to be last.
useLiteralKeys
Enforces dot notation instead of square bracket notation for member access with static names
Example fix:
foo["bar"]
->foo.bar
Require the use of
===
and!==
.useValidForDirection
Check the condition and update of for loops to detect infinite loops
Example error:
for (let i = 0; i < 10; i--) {}
for (let i = 0; i > 10; i++) {}
Enforce that getter functions have a
return
statement on all exit pathsExample error:
const obj = { get prop() {} };
Disallow
async
functions asPromise
executorsExample error:
new Promise(async (resolve, reject) => {})
Disallow lexical declarations in switch clauses.
noClassAssign
Disallow assigning to the variable created by a class declaration
Example error:
class A {}; A = 0;
noAssignInExpressions
)Disallow assignment expression in conditions
Example error:
if(a = "b") {}
Disallow the use of
console
.Disallow constant expressions in conditions.
Disallow returning a value from a constructor.
Disallow control characters in regex.
noConstAssign
Disallow assigning to constant bindings
Example error:
const a = 10; a = 0;
Disallow the use of
debugger
.Disallow the use of the
delete
operator on a variable.Disallow multiple arguments of the same function from having the same name
Example error:
function (a, b, a) {}
noDuplicateClassMembers
Disallow multiple members of the same class from having the same name
Example error:
class A { foo() {}; foo() {} }
Disallow multiple if statements in the same chain from having the same condition
Example errors:
if (a) {} else if (b) {} else if (a) {}
noDuplicateObjectKeys
Disallow multiple members in the same object expression from having the same name
Example error:
const obj = { foo: 'bar', foo: 'baz' };
noDuplicateCase
Disallow multiple case clauses in the same switch statement from having the same condition
Example error:
switch(a) { case 1: break; case 2: break; case 1: break; }
Disallow else blocks for if statements ending with a return
Example fix:
if (a) { return 1; } else { return 2; }
->if (a) { return 1; } return 2;
Disallow empty block statements.
Should be merged with
no-empty-static-block
?Disallow empty character classes in RegExp literals
Example error:
/abc[]/
noEmptyPattern
Disallow empty destructuring patterns
Example errors:
const {} = object;
const [] = array;
Should be merged with
no-empty-block
?Disallow the use of
eval
.noClassAssign
Disallow assigning to the exception binding in a catch clause
Example error:
try {} catch (err) { err = 10; }
Disallow calling
.bind()
on functions that never accessthis
Disallow unnecessary boolean casts.
noUselessLabel
Disallow using single-level deep labelled breaks
Example fix:
label: while(true) { break label; }
->while(true) { break; }
noFallthroughSwitchClause
Disallow fallthrough between case clauses in switch statements
Example error:
switch (a) { case 1: stmt(); case 2: stmt(); }
noFunctionAssign
Disallow assigning to the variable created by a function declaration
Example error:
function a() {}; a = 0;
Disallow assignment to native objects or readonly global variables.
Disallow shorthand type conversions
Example fixes:
!!cond
->Boolean(cond)
+num
->Number(num)
noImportAssign
Disallow assigning to the binding created by an import
Example error:
import { a } from "source"; a = 0;
noInnerDeclarations
Disallow function declarations in nested statements
Example error:
if (a) { function foo() {} }
Disallow all whitespace characters that are not spaces or tabulations
Disallow if statements as the only statement in an else block
Example fix:
if (a) {} else { if (b) {} }
->if (a) {} else if (b) {}
Disallow labels that share a name with a variable
Disallow useless block statements.
Suggested name:
noUselessBlock
.noPrecisionLoss
Disallow numeric literals whose value cannot be accurately represented by a double precision float
Example error:
5123000000000000000000000000001
Disallow
new
onBoolean
,String
, andNumber
.See also the unicorn section.
Disallow \8 and \9 escape sequences in string literals.
Disallows characters which are made with multiple code points in character class syntax
Example error:
/[❇️]/
Disallow new operators with global non-constructor functions.
Should replace
no-new-symbo
?noNewSymbol
Disallows calling the
Symbol
function as a constructorExample error:
new Symbol("foo")
noGlobalObjectCalls
Disallows calling global builtin objects as functions (this might be better suited for a typechecker ?)
Example errors:
Math()
JSON()
Disallow reassigning function parameters.
noPrototypeBuiltins
Disallow calling methods from
Object.prototype
directly on object instancesExample error:
foo.hasOwnProperty("bar")
Disallow variable, function, class, and type redeclarations in the same scope.
Disallow unclear usage of multiple space characters in regular expression literals.
Disallow comma operator.
noSelfAssign
Disallow assigning a variable to itself
Example error:
foo = foo;
Disallow comparisons where both sides are exactly the same.
noSetterReturn
Disallow returning a value in a setter
Example error:
const obj = { set prop(value) { this._value = value; return value; } };
Disallow identifiers from shadowing restricted names.
Disallow sparse arrays
noUnreachableSuper
Disallow using
this
before callingsuper
in a derived classExample error:
class A extends B { constructor() { this.foo = "bar"; super(); } }
noUndeclaredVariables
Disallow the use of undeclared variables
Disallow useless unefined initialization.
Suggested name:
noUselessUndefinedIntializion
.Disallow ternary expressions when a simpler alternative exists
Example fixes:
cond === 4 ? true : false
->cond === 4
value ? value : 4
->value || 4
Disallow unreachable code
noUnreachable
Disallow code that is statically known to be never reached by control flow
Example error:
function foo() { return; stmt(); }
noUnsafeFinally
Disallow control flow statement in
finally
blocksExample error:
try {} finally { return; }
Disallow using unsafe negation.
noUnsafeOptionalChaining
Disallows optional chaining in contexts where
undefined
is not allowed (this might be better suited for a typechecker ?)Example errors:
"key" in obj?.foo
inst instanceof obj?.foo
(obj?.foo)()
(obj?.foo).bar
Disallow useless call to
Function#call
andFunction#apply
.Disallow unnecessary catch clauses.
Disallow unnecessary constructors.
Disallow useless character escape.
Disallow renaming import, export, and destructured assignments to the same name.
noUnusedLabels
Enforces labeled statements are referenced by a labelled break.
Disallow unused variables.
Disallow useless backreference in regex.
useLiteralKeys
Disallow computed keys with literals in object expressions
Example fix:
{ ["a"]: "b" }
->{ a: "b" }
noUselessRename
Disallow aliasing a symbol to the same identifier in object patterns and import / export statements
Example fixes:
const { a: a } = obj;
->const { a } = obj;
import { a as a } from "source";
->import { a } from "source";
export { a as a };
->export { a };
Disallow returning
undefined
as the terminating statement of a functionExample fix:
function foo() { stmt(); return; }
->function foo() { stmt(); }
Disallow the use of
var
.Disallow the use of
void
operators, which is not a familiar operator.noUselessRename
)Enforce shorthand syntax in object expressions
Example fixes:
const obj = { a: a };
->const obj = { a };
const obj = { a: function() {} };
->const obj = { a() {} };
Disallow
with
statements in non-strict contexts.Disallow multiple variable declarations in the same variable statement.
Enforces the use of shorthand operator assignment
Example fix:
a = a + b;
->a += b;
useArrowFunction
)Prefer arrow functions to function expressions
Example fix:
.then(function (res) {})
->.then((res) => {})
Require const declarations for variables that are never reassigned after declared.
Prefer destructuring patterns for array and objects
Example fix:
const a = array[0];
->const [a] = array;
const a = object.a;
->const { a } = object;
useExponentiationOperator
Prefer using the exponentiation operator to calling
Math.pow
Example fix:
Math.pow(a, b)
->a ** b
useNumericLiterals
Disallow calling
parseInt
with string literalsExample fixes:
parseInt("23")
->23
parseInt("10111", 2)
->0b10111
parseInt("27", 8)
->0o27
parseInt("17", 16)
->0x17
Prefer
Object.hasOwn()
overObject.prototype.hasOwnProperty.call()
Example fix:
Object.prototype.hasOwnProperty.call(obj, "a")
->Object.hasOwn(obj, "a")
Prefer object spread members to calling
Object.assign
Example fix:
Object.assign({}, foo, { bar: 'baz' })
->{ ..foo, bar: 'baz' }
Disallow calling the RegExp constructor with string literals
Example fix:
new RegExp("abc", "u")
->/abc/u
Disallow the use of arguments.
Template literals are preferred over string concatenation.
Require generator functions to contain
yield
.useValidTypeof
Enforces comparing
typeof
expressions against valid stringsCan provide auto-fixes if the result of
typeof
is being compared to a well-known constantExample fixes:
typeof a === String
->typeof a === "string"
typeof a === undefined
->typeof a === "undefined"
useIsNan
Requires calling
isNaN
when comparing toNaN
Example error:
foo == NaN
Enforces literals are in the right hand side of comparison operations
Example fix:
if ("red" === color) {}
->if (color === "red") {}
ESLint React Hooks
useHookAtTopLevel
Checks that React Hooks are not called in non-constant control flow
Example error:
function Component({ prop }) { if(prop) { useEffect(); } }
useExhaustiveDependencies
Checks the dependencies array of React Hooks contains all referenced bindings
Example error:
function Component({ prop }) { useEffect(() => { prop(); }, []); }
ESLint TypeScript
Require that function overload signatures be consecutive.
useShorthandArrayType
Require consistently using either T[] or Array for arrays.
noBannedTypes
Disallow the uppercase primitive types
Example fixes:
let foo: String;
->let foo: string;
let foo: Boolean;
->let foo: boolean;
Example errors:
let foo: Function;
let foo: Object;
Enforce using a particular method signature syntax.
The rome rule should choose one form: Maybe the strictest one (property signature).
useNamingConvention
Enforce naming conventions for everything across a codebase
Disallows non-null assertion in locations that may be confusing
Example fix:
a! == b
->(a!) == b
noVoid
Require expressions of type void to appear in statement position.
Disallow duplicate enum member values.
noDelete
Disallow using the delete operator on computed key expressions.
noEmptyInterface
Disallows the declaration of empty interfaces
Example fixes:
interface Foo {}
->type Foo = {};
interface Bar extends Foo {}
->type Bar = Foo;
noExplicitAny
Disallows the
any
typeExample error:
const age: any = 'seventeen';
noExtraNonNullAssertion
Disallows extra non-null assertion
Example fix:
foo!!!.bar
->foo!.bar
Disallow classes used as namespaces.
Enforce the use of top-level import type qualifier when an import only has specifiers with inline type qualifiers
noInferrableTypes
Disallows explicit type declarations for variables or parameters initialized to a number, string, or boolean
Example fix:
const a: number = 10;
->const a = 10;
Disallow
void
type outside of generic or return types.Enforce valid definition of new and constructor.
noNamespace
Disallow TypeScript namespaces.
Disallow non-null assertions in the left operand of a nullish coalescing operator.
Disallow non-null assertions after an optional chain expression.
Disallow non-null assertions using the
!
postfix operator.Avoid this aliasing.
Disallow unnecessary constraints on generic types.
noUnsafeDeclarationMerging
Disallow declaration merging between interfaces and classes.
noUnusedVariables
Disallow unused variables
Disallows useless backreferences in regular expressions
noUselessEmptyExport
Disallow
export {}
when anotherimport
orexport
exists.Enforces the use of
as const
over literal typeExample fix:
let foo = 'bar' as 'bar';
->let foo = 'bar' as const;
Require each enum member value to be explicitly initialized
Enforce the use of
for of
loop over the standardfor
loop where possible.Enforce includes method over indexOf method.
See also the Unicorn section.
Enforces using function types instead of interfaces with call signatures
Example fix:
interface Foo { (): string; }
->type Foo = () => string;
Require all enum members to be literal values.
useNamespaceKeyword
Requires using
namespace
keyword overmodule
keyword to declare custom TypeScript modulesEnforce using the nullish coalescing operator instead of logical assignments or chaining.
Enforce using concise optional chain expressions instead of chained logical ands, negated logical ors, or empty objects.
Enforce
RegExp#exec
overString#match
if no global flag is provided.See also Unicorn section.
Enforce using String#startsWith and String#endsWith over other equivalent methods of checking substrings.
See also Unicorn section.
Disallow two overloads that could be unified into one with a union or an optional/rest parameter
Clippy
Checks for nested
if
statements that can be collapsed by combining their conditionsExample fix:
if (a) { if (b) {} }
->if (a && b) {}
Check for comparison operation that could be combined
Example fix:
a == b || a < b
->a <= b
Check for usage of pass-through functions with
flatMap
Example fix:
.flatMap(x => x)
->.flat()
Check for comparisons against plus-one or minus-one operations
Example fix:
a >= b + 1
->a > b
Check for variable declarations that are immediately returned
Example fix:
let a = "value"; return a;
->return "value";
Check for redundant or constant terminals in binary expressions
Example error:
a && b || a
useFlatMap
Check for calls to
map
followed by a call toflat
Example fix:
.map(func).flat()
->.flatMap(func)
noStringCaseMismatch
Check for comparison operation against literals with mismatched case
Example fix:
a.toLowerCase() === "Test"
->.toLowerCase() === "test"
switch(a.toLowerCase()) { case "Test": break; }
->switch(a.toLowerCase()) { case "test": break; }
Check for nested min-max calls where the values used for clamping are swapped
Example error:
Math.min(Math.max(value, 1), 0)
Check for usage of
forEach
that could be written as for loopsExample fix:
array.forEach(elem => {})
->for(const elem of array) {}
Checks for multiplication by -1 as a form of negation
Example fix:
foo * -1
->-foo
Check for loops that never actually loop
Example error:
while (true) { break; }
Check for constant out-of-bounds indices
Example error:
const array = [1, 2]; array[8];
useOptionalChain
Checks for expressions that could be replaced with optional chaining operations
Example fix:
if(a && a.b) { a.b(); }
->a?.b?.();
Check for closures that just call another function with the same signature
Example fix:
.map(item => foo(item))
->.map(foo)
Search for iterator or string search followed by a comparison to
-1
Example fix:
.indexOf(value) !== -1
->.includes(value)
.findIndex(func) !== -1
->.some(func)
Checks for the use of short circuit boolean conditions as a statement
Example fix:
a() && b();
->if (a()) { b(); }
Checks whether a for loop has a single element
Example fix:
for(const item of [item1]) {}
->const item = item1;
Checks for floating-point operations that can be expressed using built-in functions
Example fixes:
Math.E ** value
->Math.exp(value)
value ** 0.5
->Math.sqrt(value)
value < 0 ? -value : value
->Math.abs(value)
Checks for use of
reduce
when a more succinct alternative existsExample fix:
.reduce((acc, item) => acc || item > 2, false)
->.some(item => item > 2)
.reduce((acc, item) => acc && item > 2, true)
->.every(item => item > 2)
Check for loops that never mutate their condition
Example error:
let i = 0; while (i < 10) { stmt(); }
Unicorn
Improve regexes by making them shorter, consistent, and safer.
Move function definitions to the highest possible scope.
Require escape sequences to use consistent case.
Should be part of the formatter?
Note: the rome formatter use lowercase for hexadecimal number.
We should also use lowercase for escape sequences.
Enforce a case style for filenames.
Should be part of
useNamingConvention
?Enforce the use of
new
for all builtins, except String, Number, Boolean, Symbol and BigIntnoForEach
Prefer for…of over the forEach method.
Do not use a for loop that can be replaced with a for-of loop.
Suggested name:
useForOf
useIsArray
Use
Array.isArray()
instead ofinstanceof Array
.Disallow negation in the condition of an if statement
if
it has anelse
clausenoStaticOnlyClass
Disallow classes that only have static members.
noUselessSwitchCase
Disallow useless case in switch statements.
Enforce proper case for hexadecimal number literals.
Prefer Date.now() to get the number of milliseconds since the Unix Epoch.
Suggested name:
useDateNow
Prefer default parameters over reassignment.
Suggested name:
useDefaultParameter
Prefer
export…from
when re-exportingPrefer using a logical operator over a ternary.
Prefer omitting the catch binding parameter.
I think this should be a fix integrated in the
noUnusedVariables
Prefer
RegExp#test()
overString#match()
andRegExp#exec()
.Array-related rules
Should we merge these rules?
Prevent passing a function reference directly to iterator methods.
Disallow useless array length check before calling
every\,
some` and others.Prefer
Array#find()
andArray#findLast()
over the first or last element fromArray#filter()
.Prefer
Array#flat()
over legacy techniques to flatten arrays.useFlatMap
Prefer
Array#{indexOf,lastIndexOf}()
overArray#{findIndex,findLastIndex}()
when looking for the index of an item.Prefer
.some()
over.filter().length
check and.{find,findLast}()
.Prefer
String#at()
method for string index access andString#charAt()
.Prefer
Array#includes()
overArray#indexOf()
andArray#some()
when checking for existence or non-existence.Prefer negative index over
Array#length - index
when possible.Number-related rules
We already have noGlobalIsFinite and noGlobalIsNan.
Should we merge these rules? Not sure yet.
String-related rules
Should we merge these rules?
Prefer
String#codePointAt()
overString#charCodeAt()
andString.fromCodePoint()
overString.fromCharCode()
.Prefer
String#slice()
overString#substr()
andString#substring()
.Prefer
String#startsWith()
andString#endsWith()
overRegExp#test()
.Prefer
String#trimStart()
/String#trimEnd()
overString#trimLeft()
/String#trimRight()
.Beta Was this translation helpful? Give feedback.
All reactions