7 Tips For Clean Code
Tags: discuss, codequality
Published: 2021-07-26 09:33:47

It's all about maintaining clean and readable code(which works of course). So, I wanted to share a few tips with you guys. Feel free to correct me or share more tips of your own in the comments to create a learning experience for all of us. Let's get to it then:

### 1. Comments, Comments and More Comments
I'm not the ideal developer whose code is understood by everyone and I'm betting you aren't either. Instead of explaining what exactly to do, I'm going to tell you what not to do. Let's look at some sample code:

```js
// Created a constant variable "foo" and assigned a value of "bar"
const foo = "bar";
```

### 2. Meaningful Names
You want to use those kinds of names where the reader goes, "Yes! I know exactly what this does".

```js
// NEVER DO THIS
const abc = validateEmail('writecleancode@gmail.com')

// Good Job!
const isEmailValidated = validateEmail('writecleancode@gmail.com');
```

### 3. Console Warns/Errors
This is a huge problem, so many times I've seen developers commit code with eslint warnings. Infact, a couple of months ago, I started working on an existing project. When I compiled the frontend, there were over 100 warnings by jsx-ally, eslint etc.

We can use [husky] (https://www.npmjs.com/package/husky) along with [lint-staged] (https://www.npmjs.com/package/lint-staged) which will not let you commit code until you clear all the warnings and errors.


### 4. `as unknown` in Typescript
Typescript is smart, but sometimes, it just isn't smart enough! I've seen a lot of `// @ts-ignore`s or `as unknown`s in typescript code. So instead of doing this:

```
const user = dog as unknown;
```

do this:

```
const user dog as IUser
```

Even though doing this is not advisable, at least you get some type safety.


### 5. Use Babel Instead of tsc

From version 7, Babel added support for TypeScript, which means you no longer need to use the TypeScript compiler i.e. `tsc` to build your project, but instead can just use Babel which simply strips your types from all TypeScript files and then emits the result as JavaScript.

This is not only much faster than tsc, especially in bigger projects, but also allows you to use the whole Babel ecosystem within your project. For example, it's great when you want to use react or javascript features which are still in stage 3.

For back-end projects, this means you can simplify your clunky file-watching scripts and just use babel-node to watch for changes.


### 6. Use SonarJS and Eslint
Eslint has many rules that enforce best practises and conventions and will also help to prevent bugs.

(TSLint is being deprecated in favor of typescript-eslint; the TSLint plugin SonarTS has been adopted and is now part of SonarJS).

In addition to ESLint’s features, SonarJS adds some complexity checks to your code, which are helpful to just code away and then break your methods into smaller pieces.


### 7. Opaque Types
I'm not going to explain, I'll just demonstrate this to you.

Imagine we are building a banking API.

```typescript
// Account.ts

export type PaymentAmt = number;
export type Balance = number;
export type AccountNumberType = number;

function spend(accountNo: AccountNumberType, amount: PaymentAmt) {
  const account = getAccount(accountNo);
  account.balance -= amount;
}
```

```typescript
// controller.ts
import {spend} from "./accounting";

type Request = {
  body: {
    accountNumber: number,
    amount: number
  }
};

export function withdrawAmt(req: Request) {
  const {accountNumber, amount} = req.body;

  spend(amount, accountNumber);
}
```

Did you spot the bug? If you didn't, look at the place where we are calling the `spend()` function. I've (intentionally) passed the amount before the accountNumber but typescript does not complain.

If you are wondering why this happens, this is because `AccountNumberType` and `PaymentAmt` are assignable to each other because both of them are of type `number`.

There is a long standing issue in the typescript repo about this. Until the typescript team does something about this, we can use the following hack

```
// Can be used with any type
type Opaque<K, T> = T & { __TYPE__: K };

type Uuid = Opaque<"Uuid", string>;
```

The utility function Opaque<K, T> simply defines a new type that, aside from a variable’s value, also stores a (unique) key, such as Uuid. 


###Conclusion
Thanks for reading! Check out my [twitter] (https://twitter.com/AkashShyam11) where I (try) to post tips & tricks daily. Bye 🤟