Skip to main content

Fine-tune ESLint rules to write better TypeScript

Writing clean code is a lot easier with the right tools well configured.

notebook by Kelly Sikkema on Unsplash

ESLint is a static analyzer for JavaScript programs. So what does that mean and what can it do for my TypeScript code?

First things first, by static it means that you don't need to run or even compile a program to parse it. Analyzing means that it checks your code searching for flaws or bad metrics that can cause problems in the long run.

The ESLint is a linter that runs before the compiler. Witch runs before your automated tests and the end-user. Is your first line of defense and should be as integrated with your editor as possible.

For the details about integrating ESLint and VSCode, you can read my article to configure basic extensions

But ESLint would not be so popular if it was not extensible and configurable. And there is the real power and complexity. In this article, I'll walk you through the main settings and values I use to write better TypeScript.

Oh, I forgot to mention. Sure, JavaScript was the first target language for ESLint. But as a top demonstration of its inherent versatility, it can work with several parsers. And, of course, there is a TypeScript parser you can install.

🎒 Prerequisites

To complete this tutorial, you will need:

0️⃣ Sharpen your tools

Have a local copy of the tools on every project and keep it updated. It's easy to install ESLint; but remember also to install all the parsers, extensions, and plugins.

# the main tool
npm i -D eslint
# plugin and parser for typescript
nom i -D @typescript-eslint/eslint-plugin @typescript-eslint/parser
# prettier interaction
npm i -D eslint-config-prettier eslint-plugin-prettier

After finishing add them to the eslint.json configuration file.

  "parser": "@typescript-eslint/parser",
  "extends": [
  "plugins": ["prettier", "@typescript-eslint"],
  "env": {
    "browser": true,
    "es6": true,
    "node": true
  "globals": {},
  "rules": {}

Now you are good to go and write your own rules.

1️⃣ Write simple instructions

Think about you as a writer and your code as your prose. If you want to be understood, start with simple sentences. In code, sentences increase complexity with the kind and amount of operators you use.

Reduce the use of ternaries and avoid complex expressions by dividing them into simple steps.

  "max-statements-per-line": ["warn", { "max": 1 }],
  "no-nested-ternary": "warn",
  "no-unneeded-ternary": "warn",
  "one-var-declaration-per-line": ["warn", "always"],
  "operator-assignment": ["warn", "always"],
  "operator-linebreak": ["warn", "none"]

2️⃣ Write plain and small functions

Following the simile of the writer, the sentences are grouped into paragraphs. And paragraphs into chapters. The former are equivalents to our blocks (conditional or repetitive) and the latter to functions or methods (something with a name).

Reduce the size of functions, and reduce their inputs. And above all don't nest blocks within blocks within blocks...

  "max-depth": ["warn", 1],
  "max-lines-per-function": [
    { "max": 10, "skipBlankLines": true, "skipComments": true }
  "max-nested-callbacks": ["warn", 1],
  "max-params": ["warn", 2]

3️⃣ Take control of your logic

The plot of a novel is the reason you read it. Same for your business logic; that's why the code is written. The inherent complexity is unavoidable, but we must strive to spread it out and express it clearly. The last thing we want is to add unnecessary complexity.

Reduce the size of your classes by sharing responsibilities. Make it absolutely clear what choices the code can take. And distribute these paths in such a way that they can be followed without getting lost.

  "complexity": ["warn", { "max": 5 }],
  "max-lines": ["warn", 100],
  "no-else-return": "warn"

4️⃣ Add meaning and conventions to your naming

A style guide is a common tool used by magazines and publishing agencies. And so should be between software teams.

Use the same casing across the code base and name things to express intention.

  "no-magic-numbers": [
      "detectObjects": false,
      "enforceConst": true,
      "ignore": [-1, 0, 1, 2, 10, 100],
      "ignoreArrayIndexes": true
  "@typescript-ESLint/naming-convention": [
      "selector": "default",
      "format": ["camelCase"],
      "leadingUnderscore": "forbid"
      "selector": "typeLike",
      "format": ["PascalCase"]
      "selector": "typeParameter",
      "format": ["PascalCase"],
      "prefix": ["T", "K"]
      "selector": "enumMember",
      "format": ["UPPER_CASE"]
      "selector": ["memberLike", "variableLike"],
      "types": ["boolean"],
      "format": ["PascalCase"],
      "prefix": ["can", "did", "has", "is", "must", "needs", "should", "will"]

5️⃣ Use what is needed, nothing more.

Last but not least, pay attention to things that the compiler doesn't care about. Space and optional syntax.

A consistent code base is a reader's best friend. Keep it concise and keep it clear.

  "arrow-parens": ["warn", "as-needed"],
  "block-spacing": ["warn", "always"],
  "curly": ["warn", "all"],
  "no-multiple-empty-lines": ["warn", { "max": 1, "maxEOF": 1 }],
  "no-unused-vars": "off",
  "@typescript-ESLint/explicit-member-accessibility": [
      "accessibility": "no-public",
      "overrides": {
        "parameterProperties": "explicit"
  "@typescript-ESLint/explicit-function-return-type": "warn",
  "@typescript-ESLint/no-unused-vars": "warn",
  "@typescript-ESLint/no-useless-constructor": "warn",
  "@typescript-ESLint/no-empty-function": "warn"

🧰 To take away

ESLint settings file

Following is a gist with the JSON settings you need to configure ESLint to write better TypeScript.

Gist with my ESLint settings

Feel free to leave comments or share your settings.

🌅 Conclusion

Help yourself and spread good practices across your team by enforcing ESLint rules.

There are a lot of defaults and recommended pre-configurations. But to smash it apply these rules and see how your code base shines.

learn, code, enjoy, repeat

Alberto Basalo

Popular posts from this blog

10 commandments to naming and writing clean code with TypeScript

A code writer is like any other writer; writes to be read and understood . To do so it must obey certain laws. They are so important that must be followed religiously. Being a good writer is an art. But you can be a better programmer by knowing and applying a set of standards. In this guide, I will show you TypeScript samples for the  10 rules of clean naming . When you're finished, you'll be able to write heavenly code.Let there be code naming conventions 1️⃣ Be Descriptive Add value without being repetitive. Context is key. Prefer clarity over saving space. We are not in the ‘90s’ anymore. // ❌ const width = 5 ; class Image { imageWidth = width ; } // ✅ const imageWidth = 5 ; class Image { width = imageWidth; } 2️⃣ Be Meaningful Use the same word for the same concept. Create a dictionary for business and infrastructure common words. // ❌ getClient () {} readProvider () {} postCustomer () {} // ✅ getClient ()

How to configure VSCode to code better TypeScript

Writing a more readable code is your first goal as a programmer. This initial Visual Studio Code setup makes your job easier. Any good worker must know and customize his tools for the job at hand. With minor tweaks, VSCode is the perfect tool to write TypeScript . There are plenty of guides to configure VSCode . Most of them include a lot of extensions. But almost none starts from the very beginning, with no extension at all. I am an enthusiast of writing clean code , so I do my best to promote and facilitate this goal, and I am sure that this can help you to write better code. In this post, you will learn how to adapt VS Code to write better TypeScript code, even without any extension. And above all, you will get tips to adopt good habits and detect programming vices. 🎒 Prerequisites To complete this tutorial, you will need: A local copy of Visual Studi