#
Expressions
#
Use strict equality
Always use the === (strict equality) and !== (strict inequality) operators
to compare two values. Using the same approach for all comparisons will make
your code more consistent and gives you one less thing to think about.
ESLint's eqeqeq rule should be enabled to enforce this. It also has a
"smart" option that allows == in certain conditions, and I often used it in
the past. However, using the default setting gives you more consistency and will
help everyone avoid non-productive discussions in code reviews.
#
Prefer postfix decrement/increment
When incrementing or decrementing a variable, use the prefix notation (++i)
unless the context requires the postfix notation (i++). The prefix notation is
more clear because the result of the expression has the same value as i after
evaluation, while in postfix notation the resulting value is outdated compared
to the new value of i.
for (let i = 0; i < 10; ++i) {
console.log(i);
}
Here we don't need to defer the update to i, so the prefix notation is
simpler.
Now, here's an example where the postfix notation is necessary:
console.log("Counting from 1 to 5");
let i = 1;
while (i < 6) {
console.log(i++);
}
Counting from 1 to 5
1
2
3
4
5
for (let i = 0; i < 10; i++) {
console.log(i);
}
This is a bad example because we have no reason to use the postfix notation,
since deferring the update to i is not necessary.
Now, here's an example where the prefix notation causes a problem:
console.log("Counting from 1 to 5");
let i = 1;
while (i < 6) {
console.log(++i);
}
Counting from 1 to 5
2
3
4
5
6
#
Avoid the comma operator
The comma operator allows you to evaluate a sequence of expressions as a single expression, which results in the value of the last expression. This is a confusing form of operation sequencing and should be avoided.
#
Avoid function expressions
Arrow functions should be favored over function expressions. Arrow functions are
terser and more predictable in regards to the this keyword.
const numbers = [1, 3, 5, 7];
const sum = numbers.reduce((acc, n) => acc + n, 0);
const numbers = [1, 3, 5, 7];
const sum = numbers.reduce(function (acc, n) {
return acc + n;
}, 0);
Function expression was used when not necessary. This is incorrect.
When you need a dynamically bound this, function expressions may be necessary
and are therefore allowed.
#
Avoid implicit coercion
Some ways to convert values to another type are obscure and should be avoided, here are some bad examples:
const hasItems = !!items.length;
const num = +str;
The no-implicit-coercion ESLint rule can be enabled to enforce this.
#
Avoid other types when booleans are expected
In contexts where a boolean value is expected, such as an if condition, avoid
passing non-boolean values directly. Instead, explicitly compare the value to
something in order to make the intent clear.
Contexts in which this rule applies include conditions for if, while, for,
and do-while statements. It also applies for the operands of the logical
negation ! operator, binary logical operators && and ||, and the first
operand for the conditional (ternary) operator.
declare const documents: Document[];
if (documents.length === 0) {
console.log("No documents found");
}
declare const documents: Document[];
// Bad: Non-boolean passed to "!" operator
if (!documents) {
console.log("No documents found");
}
The strict-boolean-expressions ESLint rule can be enabled to enforce this.
#
Prefer nullish coalescing
Use the nullish coalescing operator (??) instead of the logical OR operator
(||) when you want a fallback value for when an expression is null or
undefined.
When you really want to check for falsy values, you may freely use the logical OR operator.
declare const bar: string | null | undefined;
const foo = bar ?? "default"; // Here we are handling only null and undefined
declare const owo: string | boolean;
const awoo = owo || "default"; // OK, we are checking for falsy values
declare const bar: string | null | undefined;
const foo = bar || "default"; // May be bad, this will also trigger for an empty
// string
The prefer-nullish-coalescing ESLint rule can be enabled to enforce this.