☂️ 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.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
ESLint
Disallow functions that exceed a given complexity score.
noInvalidConstructorSuperVerify
super()is called in constructors of derived classes, and not called in constructor of non-derived classes (this rule also tries to check if theextendsreference 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.
useLiteralKeysEnforces dot notation instead of square bracket notation for member access with static names
Example fix:
foo["bar"]->foo.barRequire the use of
===and!==.useValidForDirectionCheck 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
returnstatement on all exit pathsExample error:
const obj = { get prop() {} };Disallow
asyncfunctions asPromiseexecutorsExample error:
new Promise(async (resolve, reject) => {})Disallow lexical declarations in switch clauses.
noClassAssignDisallow 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.
noConstAssignDisallow assigning to constant bindings
Example error:
const a = 10; a = 0;Disallow the use of
debugger.Disallow the use of the
deleteoperator on a variable.Disallow multiple arguments of the same function from having the same name
Example error:
function (a, b, a) {}noDuplicateClassMembersDisallow 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) {}noDuplicateObjectKeysDisallow multiple members in the same object expression from having the same name
Example error:
const obj = { foo: 'bar', foo: 'baz' };noDuplicateCaseDisallow 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[]/noEmptyPatternDisallow empty destructuring patterns
Example errors:
const {} = object;const [] = array;Should be merged with
no-empty-block?Disallow the use of
eval.noClassAssignDisallow assigning to the exception binding in a catch clause
Example error:
try {} catch (err) { err = 10; }Disallow calling
.bind()on functions that never accessthisDisallow unnecessary boolean casts.
noUselessLabelDisallow using single-level deep labelled breaks
Example fix:
label: while(true) { break label; }->while(true) { break; }noFallthroughSwitchClauseDisallow fallthrough between case clauses in switch statements
Example error:
switch (a) { case 1: stmt(); case 2: stmt(); }noFunctionAssignDisallow 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)noImportAssignDisallow assigning to the binding created by an import
Example error:
import { a } from "source"; a = 0;noInnerDeclarationsDisallow 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.noPrecisionLossDisallow numeric literals whose value cannot be accurately represented by a double precision float
Example error:
5123000000000000000000000000001Disallow
newonBoolean,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?noNewSymbolDisallows calling the
Symbolfunction as a constructorExample error:
new Symbol("foo")noGlobalObjectCallsDisallows calling global builtin objects as functions (this might be better suited for a typechecker ?)
Example errors:
Math()JSON()Disallow reassigning function parameters.
noPrototypeBuiltinsDisallow calling methods from
Object.prototypedirectly 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.
noSelfAssignDisallow assigning a variable to itself
Example error:
foo = foo;Disallow comparisons where both sides are exactly the same.
noSetterReturnDisallow 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
noUnreachableSuperDisallow using
thisbefore callingsuperin a derived classExample error:
class A extends B { constructor() { this.foo = "bar"; super(); } }noUndeclaredVariablesDisallow 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 === 4value ? value : 4->value || 4Disallow unreachable code
noUnreachableDisallow code that is statically known to be never reached by control flow
Example error:
function foo() { return; stmt(); }noUnsafeFinallyDisallow control flow statement in
finallyblocksExample error:
try {} finally { return; }Disallow using unsafe negation.
noUnsafeOptionalChainingDisallows optional chaining in contexts where
undefinedis not allowed (this might be better suited for a typechecker ?)Example errors:
"key" in obj?.fooinst instanceof obj?.foo(obj?.foo)()(obj?.foo).barDisallow useless call to
Function#callandFunction#apply.Disallow unnecessary catch clauses.
Disallow unnecessary constructors.
Disallow useless character escape.
Disallow renaming import, export, and destructured assignments to the same name.
noUnusedLabelsEnforces labeled statements are referenced by a labelled break.
Disallow unused variables.
Disallow useless backreference in regex.
useLiteralKeysDisallow computed keys with literals in object expressions
Example fix:
{ ["a"]: "b" }->{ a: "b" }noUselessRenameDisallow 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
undefinedas the terminating statement of a functionExample fix:
function foo() { stmt(); return; }->function foo() { stmt(); }Disallow the use of
var.Disallow the use of
voidoperators, 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
withstatements 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;useExponentiationOperatorPrefer using the exponentiation operator to calling
Math.powExample fix:
Math.pow(a, b)->a ** buseNumericLiteralsDisallow calling
parseIntwith string literalsExample fixes:
parseInt("23")->23parseInt("10111", 2)->0b10111parseInt("27", 8)->0o27parseInt("17", 16)->0x17Prefer
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.assignExample fix:
Object.assign({}, foo, { bar: 'baz' })->{ ..foo, bar: 'baz' }Disallow calling the RegExp constructor with string literals
Example fix:
new RegExp("abc", "u")->/abc/uDisallow the use of arguments.
Template literals are preferred over string concatenation.
Require generator functions to contain
yield.useValidTypeofEnforces comparing
typeofexpressions against valid stringsCan provide auto-fixes if the result of
typeofis being compared to a well-known constantExample fixes:
typeof a === String->typeof a === "string"typeof a === undefined->typeof a === "undefined"useIsNanRequires calling
isNaNwhen comparing toNaNExample error:
foo == NaNEnforces literals are in the right hand side of comparison operations
Example fix:
if ("red" === color) {}->if (color === "red") {}ESLint React Hooks
useHookAtTopLevelChecks that React Hooks are not called in non-constant control flow
Example error:
function Component({ prop }) { if(prop) { useEffect(); } }useExhaustiveDependenciesChecks 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.
useShorthandArrayTypeRequire consistently using either T[] or Array for arrays.
noBannedTypesDisallow 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).
useNamingConventionEnforce naming conventions for everything across a codebase
Disallows non-null assertion in locations that may be confusing
Example fix:
a! == b->(a!) == bnoVoidRequire expressions of type void to appear in statement position.
Disallow duplicate enum member values.
noDeleteDisallow using the delete operator on computed key expressions.
noEmptyInterfaceDisallows the declaration of empty interfaces
Example fixes:
interface Foo {}->type Foo = {};interface Bar extends Foo {}->type Bar = Foo;noExplicitAnyDisallows the
anytypeExample error:
const age: any = 'seventeen';noExtraNonNullAssertionDisallows extra non-null assertion
Example fix:
foo!!!.bar->foo!.barDisallow classes used as namespaces.
Enforce the use of top-level import type qualifier when an import only has specifiers with inline type qualifiers
noInferrableTypesDisallows explicit type declarations for variables or parameters initialized to a number, string, or boolean
Example fix:
const a: number = 10;->const a = 10;Disallow
voidtype outside of generic or return types.Enforce valid definition of new and constructor.
noNamespaceDisallow 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.
noUnsafeDeclarationMergingDisallow declaration merging between interfaces and classes.
noUnusedVariablesDisallow unused variables
Disallows useless backreferences in regular expressions
noUselessEmptyExportDisallow
export {}when anotherimportorexportexists.Enforces the use of
as constover 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 ofloop over the standardforloop 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.
useNamespaceKeywordRequires using
namespacekeyword overmodulekeyword 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#execoverString#matchif 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
ifstatements 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 <= bCheck for usage of pass-through functions with
flatMapExample fix:
.flatMap(x => x)->.flat()Check for comparisons against plus-one or minus-one operations
Example fix:
a >= b + 1->a > bCheck 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 || auseFlatMapCheck for calls to
mapfollowed by a call toflatExample fix:
.map(func).flat()->.flatMap(func)noStringCaseMismatchCheck 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
forEachthat 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->-fooCheck 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];useOptionalChainChecks 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
-1Example 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
reducewhen 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
newfor all builtins, except String, Number, Boolean, Symbol and BigIntnoForEachPrefer for…of over the forEach method.
Do not use a for loop that can be replaced with a for-of loop.
Suggested name:
useForOfuseIsArrayUse
Array.isArray()instead ofinstanceof Array.Disallow negation in the condition of an if statement
ifit has anelseclausenoStaticOnlyClassDisallow classes that only have static members.
noUselessSwitchCaseDisallow 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:
useDateNowPrefer default parameters over reassignment.
Suggested name:
useDefaultParameterPrefer
export…fromwhen 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
noUnusedVariablesPrefer
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.useFlatMapPrefer
Array#{indexOf,lastIndexOf}()overArray#{findIndex,findLastIndex}()when looking for the index of an item.Prefer
.some()over.filter().lengthcheck 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 - indexwhen 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