What Is Strict Mode In TypeScript, Why And When You Should Use It?
Tags: javascript, typescript, beginners
Published: 2021-07-16 02:14:43

---
title: "What Is Strict Mode In TypeScript, Why And When You Should Use It?"
tags: ['javascript', 'typescript', 'beginner']
keywords: ['javascript', 'typescript']
published: true
canonical_url: "https://byte.ski/blog/article/what-is-strict-mode-in-typescript-and-why-and-when-you-should-use-it"
cover_image: "https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iyrcabdsmdsj5y9h0ak8.jpeg"
---

This post is part of series and [book about TypeScript](https://byte.ski/typescript-book). It will guide you from scratch to writing full TypeScript applications on Back End and Front End. The series is available as **PDF eBook** for **free** to **everyone**.

<a href="https://byte.ski/typescript-book"><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/idg3cmsrhuu0jqx5bulp.png" alt="TypeScript Book (PDF)" /></a>  

There are many options and parameters that can be used in the TypeScript configuration. One of the important "groups" of options is strict options. These options provide us the ability to write the safest code. How? Because TypeScript was developed primarily as **superset of JavaScript**, by default it allows us to write code that is not super strict in types and other aspects. It was made like this because TypeScript should be easily used by JavaScript developers. JavaScript doesn't have static types and is more flexible in some aspects of programming. It has many features to write code *faster* and *easier* (at first). However, the other side of this is that you probably will have more places where your code is unsafe. It means that the count of cases where your program will fall is big. TypeScript partially solves this problem. 

## What Is Strict Mode?

You may probably have heard about [JavaScript](https://byte.ski/notes/JavaScript) strict mode and [TypeScript](https://byte.ski/notes/TypeScript) strict mode. The point is that they are different kinds of things. 

TypeScript strict mode is a bunch of TypeScript compiler parameters (that can be also be represented by one "main" parameter) that make TypeScript compiler **tsc** force you to follow specific rules of writing code in TypeScript. All these rules are directly related to **types** and **managing types** in the TypeScript code. For example, one of the rules forces you to always write a type of parameter in every function.

TypeScript "strict mode" could be enabled in the TypeScript configuration file by one OR a few parameters. It's a group of parameters that can be enabled individually or can be enabled all at once by one parameter.

The "main strict mode" parameter is called **strict**. It is a part of **compilerOptions** in **tsconfig.json**. If you set this parameter to **true** it will automatically set specific several parameters of configuration to **true**. Another important nuance is that if you enable **strict** parameter instead of individual strict checks parameters, the TypeScript compiler will *automatically* check your code with all new strict checks parameters that TypeScript may have in the next versions. 

Strict checks parameters are:

- noImplicitAny
- strictNullChecks
- strictFunctionTypes
- strictBindCallApply
- strictPropertyInitialization
- noImplicitThis
- alwaysStrict

I will introduce you to each of these parameters in next posts of the series. Let's focus on **strict mode** itself.

## Should I Use Strict Mode?

What happens when you set this parameter to **true**? Well, it depends on is your project new (just created) or not. If you don't have any code in your project except configuration files or files with boilerplate code that was generated by tools like [create-react-app](https://byte.ski/notes/create-react-app) then **tsc** should compile the project without errors. But if your project is not new, have a huge amount of files and code and you didn't follow specific rules of strict mode then you probably will get a list of errors provided by **tsc** after you attempted to compile the project.

And this is an answer to the question "Should I use strict mode in TypeScript or not?". If you just start a new project **I highly recommend using strict mode in TypeScript**. It will help you to avoid errors, typos, and mistakes in your code in the future. Strict mode constricts you in ways of writing your code. On other hand, you won't choose the way that will bring you to make a mistake. Sometimes a simple, verbose, and "boring" code is better than "cool" one-line code because it won't be failed. 

Why strict mode in TypeScript can be enabled by several parameters? These parameters can be used in an existing project. You probably won't be able to set parameter **strict** to true in an existing project. But you can set some strict mode parameters to gradually rewrite your codebase following strict mode rules. For example, you can set the parameter **noImplicitAny** to **true** and rewrite your code to one that is following this rule (you should write a type of parameters in every function). You probably won't have time to rewrite all projects but you can improve specific parts of your code. Next time when you will have time to improve code quality you can set one more strict mode parameter (that suits your by time, number of changes in code, etc).

## In Practice

Let's look at the example. Here is the simple console app that asks a user to type its name and then if the user exists in a database (which is basically [JSON](https://byte.ski/notes/JSON) file with an array of users) prints greetings in a terminal. The source of an example is available [here](https://github.com/kowalevski/ts-node-sample/tree/strict-mode-example). Just create a new TypeScript project and create a few files with the code presented below.

```bash
git clone https://github.com/kowalevski/ts-node-sample/tree/strict-mode-example
```

The app has three files or modules with functions. The entry point of the app is file **src/main.ts**:

```ts
import { createQuestioner } from "./createQuestioner";
import { greeting } from "./greeting";
import usersDB from './users.json';

async function main() {
  try {
    const questioner = createQuestioner();
    const username = await questioner.ask("Type your name: ");

    const foundUser = usersDB.find((user) => user.username === username);

	greeting(foundUser.username);

    questioner.finishUp();
  } catch (e) {
    console.error(e);
    process.exit();
  }
}

main();
```

We are not interested in the module **createQuestioner**. Let's perceive it as a third-party library with some API. What we really need to focus on is file **src/greeting.ts**:

```ts
export function greeting(names) {
  console.log(`Hello, ${names.map((name) => name.toLowerCase()).join(', ')}!`);
}
```

Pretty simple code, isn't it? We didn't specify the type of parameter names but we expect that there will be an array of strings. 

Okay, let's run our small application. Did you see any issues in the code? Because **strict mode** is disabled in the TypeScript configuration of this app we shouldn't see any errors in the editor.

Run the app by the following command:

```bash
tsc && node dist/main.js
```

Or

```bash
npm run dev
```

After typing a name (it can be whatever name you want) you should see that there are errors in our code. But they were identified only after running **Node**, i.e. in runtime. So, the TypeScript compiler didn't find any problems in the code. 

Now, let's enable **strict mode** and see what happens. After enabling **strict** parameter in **tsconfig.json** you should see errors in your editor (if it supports TypeScript):

![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jxsb705df03jzelez2c5.png)

And if you run TypeScript compilation you will see that TypeScript highlight the error:

```
src/greeting.ts:1:26 - error TS7006: Parameter 'names' implicitly has an 'any' type.

1 export function greeting(names) {
                           ~~~~~

src/greeting.ts:2:36 - error TS7006: Parameter 'name' implicitly has an 'any' type.

2   console.log(`Hello, ${names.map((name) => name.toLowerCase()).join(', ')}!`);
                                     ~~~~
Found 2 errors
```

Basically, the problem is that we didn't specify the type of parameter **names** in a function **greeting**. It means that the function can be called with wrong arguments in module **main**. Specify the type in **src/greeting.ts**. It should be an array of string values:

```ts
export function greeting(names: string[]) {
  console.log(`Hello, ${names.map((name) => name.toLowerCase()).join(', ')}!`);
}
```

Great! Let's see that we have in a file **main.ts**. In an editor, you probably may see that there is an error. Let's run TypeScript and see what's wrong here.

```
src/main.ts:12:14 - error TS2345: Argument of type '{ username: string; age: number; } | undefined' is not assignable to parameter of type 'string[]'.
  Type 'undefined' is not assignable to type 'string[]'.

12     greeting(foundUser.username);
                ~~~~~~~~~~~~~~~

Found 1 error
```

Okay. So, the problem is that we put a value of variable **foundUser** as itself (it is an object or undefined) but a function **greeting** receives an array of string values. It seems like a small typo because all we need to do is write argument **foundUser.username** as bracketed. Also, because variable **foundUser** could be *undefined* we need to check that is it false or not:


```ts
async function main() {
  try {
    const questioner = createQuestioner();
    const username = await questioner.ask("Type your name: ");

    const foundUser = usersDB.find((user) => user.username === username);

    if (!foundUser) {
        console.log('User is not found');
        questioner.finishUp();
        return;
    }

    greeting([foundUser.username]);

    questioner.finishUp();
  } catch (e) {
    console.error(e);
    process.exit();
  }
}
```

Now, let's run the app again:

```
npm run dev
```

It should work correctly.

## Conclusions

So now you know that even code that compiles by **tsc** successfully can have issues and incorrect behavior when this code is running. The goal of TypeScript is to prevent times when the application works with errors or doesn't work at all ***before*** the code of the application executes. TypeScript analysis your code and based on types that were specified by you or by *type inference* and highlight part of the code with potential risk. And the best way it works is in **strict mode**. Using **strict mode** you will catch more potential errors and typos in your codebase before running the program.

***Do you like the material? Please, [subscribe to my email newsletter](https://byte.ski/newsletter) to stay up to date.***

<a href="https://byte.ski/newsletter"><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fld1yqfgvgz2dgcpho0x.png" alt="subscribe" /></a>