-
Notifications
You must be signed in to change notification settings - Fork 0
Coding Style Guide
- Coding style guide
When defining a class or an enum, the file containing the code should have a name that matches the name of the class or enum.
// File: MyClass.ts
class MyClass {
}
For files containing groups of related functions, the file name should describe the purpose of those functions.
// File: StringUtils.ts
export function capitalizeFirstLetter(input: string) {
}
export function truncateString(input: string, maxLength: number) {
}
Instead of using spaces or underscores, separate words in a folder and file name with hyphens.
my-file-name.ts
The main branch is labeled main
.
Development branches are labeled features/<name>
.
where <name>
is a short name for what is changing.
- Pascal or camel case for branch names e.g.
newFeature
orNewFeature
- Don’t use
/
or\
, except to separate prefixes from the name of the branch - Don’t use special characters
Add a new feature
-
Acceptable:
feature/newFeature
-
Unacceptable:
feature/newfeature
The subject of a PR should be a short summary of what is being done by the pull request. This is what will appear in your git history, so it should be informative but concise.
Try to keep your first line short, focused, and to the point.
Write in an imperative tone.
Example
-
Good:
Add a versioning feature to the FooBar application
-
Not Recommended:
Adding a versioning feature to the FooBar application
This is a longer description of your pull request. It should cover details on what problem is being solved, why this is a good solution, and adds more context about the implementation.
Example:
Fixes #24
Documentation and version mismatch is now handled using versioning. Documentation will be published with a version number matching the package allowing users to find the applicable documentation for their version.
Order of operations:
1. Devs make changes
2. Version bump
3. Package released
4. New docs uploaded to the version folder
5. Pointer to latest documentation updated
The name of a variable, function, or class, should answer all the big questions. It should tell you why it exists, what it does, and how it is used. If a name requires a comment, then the name does not reveal its intent.
Use meaningful variable names.
Distinguish names in such a way that the reader knows what the differences offer.
Bad:
function isBetween(a1: number, a2: number, a3: number): boolean {}
Good:
function isBetween(value: number, left: number, right: number): boolean {}
Use pronounceable variable names
If you can't pronounce it, you can't discuss it without sounding weird.
Bad:
class Subs {
public ccId: number;
public billingAddrId: number;
public shippingAddrId: number;
}
Good:
class Subscription {
public creditCardId: number;
public billingAddressId: number;
public shippingAddressId: number;
}
Don't use abbreviations
Bad:
class App {
public usr: string;
public pwd: string;
public authTkn: string;
}
Good:
class Application {
public username: string;
public password: string;
public authenticationToken: string;
Avoid mental mapping
Explicit is better than implicit.
Clarity is king.
Bad:
const u = getUser();
const s = getSubscription();
const t = charge(u, s);
Good:
const user = getUser();
const subscription = getSubscription();
const transaction = charge(user, subscription);
Don't add unneeded context
If your class/type/object name tells you something, don't repeat that in your variable name.
Bad:
type Car = {
carMake: string;
carModel: string;
carColor: string;
}
function print(car: Car): void {
console.log(`${car.carMake} ${car.carModel} (${car.carColor})`);
}
Good:
type Car = {
make: string;
model: string;
color: string;
}
function print(car: Car): void {
console.log(`${car.make} ${car.model} (${car.color})`);
}
- Use camelCase for variable and function names (except for React functional components)
Bad:
var FooVar;
function BarFunc() { }
Good:
var fooVar;
function barFunc() { }
- Use PascalCase for React functional components
Bad:
const userProfile: React.FC = () => {
}
Good:
const UserProfile: React.FC = () => {
}
- Use camelCase of class members, interface members, methods and methods parameters
Bad:
class Foo {
Bar: number;
Baz() { }
}
Good:
class Foo {
bar: number;
baz() { }
}
- Use PascalCase for class names and interface names.
Bad:
class foo { }
Good:
class Foo { }
- Use PascalCase for enums and camelCase for enum members
Bad:
enum notificationTypes {
Default = 0,
Info = 1,
Success = 2,
Error = 3,
Warning = 4
}
Good:
enum NotificationTypes {
default = 0,
info = 1,
success = 2,
error = 3,
warning = 4
}
- Don't use negative names for boolean variables.
Bad:
const isNotEnabled = true;
Good:
const isEnabled = false;
- A prefix like is, are, or has helps every developer to distinguish a boolean from another variable by just looking at it
Bad:
const enabled = false;
Good:
const isEnabled = false;
Use plural names for arrays that represent a collection or list of items.
const products: Product[] = [product1, product2, product3];
Use singular names for objects that represent a single entity or instance of a type.
const myCar: Car = {
make: 'Toyota',
model: 'Camry',
year: 2022,
color: 'Silver',
};
- OTBS (one true brace style). Wikipedia
The one true brace style is one of the most common brace styles in TypeScript, in which the opening brace of a block is placed on the same line as its corresponding statement or declaration.
if (foo) {
bar();
}
else {
baz();
}
-
Do not omit curly brackets
-
Always wrap the body of the statement in curly brackets.
Use 2 spaces. Not tabs.
Use semicolons.
So when you find yourself in a position where you need to write a comment, think it through and see whether there isn't some way to turn the tables and express yourself in code. Every time you express yourself in code, you should pat yourself on the back. Everytime you write a comment, you should grimace and feel the failure of your ability of expression.
Bad Comments
Most comments fall into this category. Usually they are crutches or excuses for poor code or justifications for insufficient decisions, amounting to little more than the programmer talking to himself.
Mumbling
Plopping in a comment just because you feel you should or because the process requires it, is a hack. If you decide to write a comment, then spend the time necessary to make sure it is the best comment you can write.
Noise Comments
Sometimes you see comments that are nothing but noise. They restate the obvious and provide no new information.
// redirect to the Contact Details screen
this.router.navigateByUrl(`/${ROOT}/contact`);
// self explanatory, parse ...
this.parseProducts(products);
Comments
Comments can sometimes be useful:
- When explaining why something is being implemented in a particular way.
- When explaining complex algorithms (when all other methods for simplifying the algorithm have been tried and come up short).
Comment conventions
-
Write comments in English.
-
Do not add empty comments
-
Begin single-line comments with a single space
Good:
// Single-line comment
Bad:
//Single-line comment
// Single-line comment
-
Write single-line comments properly
- Single-line comments should always be preceded by a single blank line.
- Single-line comments should never be followed by blank line(s).
Good:
const x;
// This comment is valid
const y;
Bad:
const x;
// This comment is not valid
const y;
const x;
// This comment is not valid
const y;
-
Do not write embedded comments
- Do not write comments between declaration of statement and opening curly brackets.
- Place comments above statements, or within statement body.
Good:
// This method does something..
public method() {
}
Bad:
public method() { // This method does something..
}
public method() {
// This method does something..
}
Avoid using return types. In simple functions like makeId, TypeScript knows what you're returning. This return type ends up just being extra code that you need to maintain.
Bad:
function foo(): int {
}
function foo() {
let bar: int = 6;
}
Good:
function foo() {
}
The "Return Early" principle is a coding approach that suggests structuring functions or methods so that the expected positive result is returned at the end, and the execution terminates early when conditions are not met. This practice aims to enhance code readability and maintainability. Key observations include:
Nonlinear Flow Issues:
- Nested conditions in traditional approaches make code hard to follow.
- Difficulty in identifying corresponding "else" blocks, leading to confusing error handling.
- The need to navigate through nested "ifs" to find the expected positive result.
Return Early Approach:
- Code has one level of indentation, making it more linear and readable.
- Focus on finding errors first, enhancing bug prevention.
- Utilizes a fail-fast mindset similar to Test-Driven Development, making code easier to test.
- Immediate termination on errors prevents unintended code execution.
Bad:
def check_number_properties(num):
if num > 0:
if num % 2 == 0:
if num > 10:
return;
else:
return;
else:
return;
else:
return;
Good:
def check_number_properties(num):
if num <= 0:
return;
if num % 2 != 0:
return;
if num <= 10:
return;
return;
- Define React components as functions, not as classes.
- Use functional components for simplicity and readability.
- Utilize hooks for state management and side effects.
Bad:
class MyComponent extends React.Component {
render() {
return (
<div>
<p>{this.props.prop1}</p>
<p>{this.props.prop2}</p>
</div>
);
}
}
Good:
const MyComponent = ({ prop1, prop2 }) => (
<div>
<p>{prop1}</p>
<p>{prop2}</p>
</div>
);
Declaring only one component per file improves readability and reusability of components.
Bad:
var Hello = createReactClass({
render: function() {
return <div>Hello {this.props.name}</div>;
}
});
var HelloJohn = createReactClass({
render: function() {
return <Hello name="John" />;
}
});
Good:
var Hello = require('./components/Hello');
var HelloJohn = createReactClass({
render: function() {
return <Hello name="John" />;
}
});
- Follow the config guide from MUI: https://mui.com/material-ui/guides/nextjs/#configuration
- Material UI - Next.js App Router example: https://github.com/mui/material-ui/tree/master/examples/material-ui-nextjs