JavaScript & TypeScript
Syntax
-
Use 2 spaces for indentation
function hello (name) {
console.log('hi', name);
} -
Use semicolons
window.alert('hi') // Don't
window.alert('hi'); // Do -
Use single quotes for strings (except if escaping)
console.log("hello there"); // Don't
console.log(`hello there`); // Don't
console.log('hello there'); // Do
console.log("hello 'there'"); // Do
console.log(`hello ${name}`); // Do -
Add a space after keywords
if(statement) { ... } // Don't
if (statement) { ... } // Do -
Always use
===instead of==if (name == 'John') // Don't
if (name != 'John') // Don't
if (name === 'John') // Do
if (name !== 'John') // Do -
Infix operators must be spaced
// Don't
let x=2;
let message = 'hello, '+name+'!';
// Do
let x = 2;
let message = 'hello, ' + name + '!'; -
Add a space after commas
// Don't
let list = [1,2,3,4];
function greet (name,options) { ... }
// Do
let list = [1, 2, 3, 4];
function greet (name, options) { ... } -
Keep else statements on the same line as their curly braces
// Don't
if (condition) {
// ...
}
else {
// ...
}
// Do
if (condition) {
// ...
} else {
// ...
} -
Always use curly braces for if statements
// Don't
if (condition) console.log('done');
if (condition)
console.log('done');
// Do
if (condition) {
console.log('done');
} -
place
?and:on their own lines when using ternary operator in a multi-line setting// Don't
let location = env.development ?
'localhost' :
'www.api.com';
// Do
let location = env.development ? 'localhost' : 'www.api.com';
let location = env.development
? 'localhost'
: 'www.api.com'; -
Write each declaration in its own statement
// Don't
let silent = true, verbose = true;
let silent = true,
verbose = true;
// Do
let silent = true;
let verbose = true; -
Add spaces inside single line blocks.
function foo () { return true } // Do
function foo () {return true} // Don't -
Use trailing commas
let obj = {
message: 'hello',
ephemeral: true, // Do
}
let obj = {
message: 'hello',
ephemeral: true // Don't
} -
Dots should be on the same line as the property
// Do
console
.log('hello');
// Don't
console.
log('hello'); -
Files must end with a newline
-
Don't insert spaces between function identifiers and their invocations
console.log('hello'); // Do
console.log ('hello'); // Don't -
Don't use floating decimals
const discount = 0.5; // Do
const discount = .5; // Don't
Naming
Variables
Variables should always have meaningful names (acronyms are not sufficient) and be written in lowerCamelCase. Exceptions for acronyms might only be common use cases like the iterator inside a for loop.
let myVar = 'hello'; // Do
let my_var = 'hello'; // Don't
// excetption
for (let i; i < 0; i++) { ... }
// Avoid
teams.forEach(t => { ... });
// Prefer
teams.forEach(team => { ... });
Functions
Functions should always be as descriptive as possible and be written in lowerCase. Generally speaking, the more generic a function is, the shorter its name is.
function myFunction () { } // Do
function my_function () { } // Don't
Types
Types should be written in UpperCamelCase. Inside of interface blocks each declaration should end with a semicolon.
// Do
interface Todo {
title: string;
description: string;
completed: boolean;
createdAt: number;
}
type TodoInfo = Omit<Todo, "completed" | "createdAt">;
// Don't
interface todo {
title: string,
description: string,
completed: boolean,
createdAt: number,
}
type todoInfo = Omit<Todo, "completed" | "createdAt">;
Classes
Types should be written in UpperCamelCase.
class Animal { } // Do
class animal { } // Don't
Use # for private properties
as JavaScript will enforce privacy encapsulation itself in this case.
class ClassWithPrivate {
// Do
#privateField;
#privateFieldWithInitializer = 42;
#privateMethod() {}
// Don't
_privateField;
_privateFieldWithInitializer = 42;
_privateMethod() {}
}
Best practices
Variable declaration
If a variable is not intended to be changed use const otherwise use let and do not use var. Also avoid modifying
variables declared using const.
const constant = 0;
let variable = 0;
var variable = 0; // Don't
constant = 1; // Don't
variable = 2;
Imports
Use a single import statement per module and break lines in case of a long import statement.
// Do
import { obj1, obj2 } from 'module';
import {
myFunc1,
myFunc2,
myFunc3,
myFunc4,
myFunc5,
} from 'module2';
// Don't
import { myFunc1 } from 'module';
import { myFunc2 } from 'module';
Nesting
Keep nesting to a bare minimum and avoid any nesting deeper than three levels of depth.
// Do
if (!session) return;
if (!sessionValid) return;
if (!user.feature.enabled) return;
// main code block
// Don't
if (session) {
if (sessionValid) {
if (user.feature.enabled) {
// main code block
}
}
}
General
-
Don't use constant expressions in conditions (except while loops)
// Do
if (x === 0) {
// ...
}
while (true) {
// only with break condition
}
// Don't
if (false) {
// ...
} -
Do not use the
eval()function -
Do not use console logs
// avoid in production
console.log('Made it here');
// ok
console.error(err);