Better Code — Thanks to “Strict mode” in TypeScript

Benji
5 min readSep 7, 2021

--

“Go ahead — nothing bad will happen”. Unfortunately, something often does.

For a long time, TypeScript Frameworks (like Angular) did not have strict type checking (known as: “Strict mode”) activated by default. The lack of this strict check means that messy code snippets remain allowed by the TypeScript compiler. It smells a little bit like anti-authoritarian education in the software business without this activated mode, following the principle of: “Go ahead — nothing bad will happen”. Unfortunately, it often does happen — we are talking about unexpectedly faulty behaviour due to missing definitions.

Angular announced the Strict mode as an experimental opt-in mode in August 2020. New projects created with the Angular CLI were, until recently, created without strict type checking by default. Today new projects and workspaces created by the Angular CLI are using Strict mode by default.

What’s the problem without Strict mode?

Let’s get into this topic with a small example.

Example without Strict mode

The following TypeScript class is possible in “Default mode” (also called “sloppy mode”):

🤫 Spoiler alert:
If the method “isNonAlcoholic()” is now called on a “Beer” object, it is possible that the alcohol content — i.e. the member “alcoholByVolume” — has not been initialised at this time and the programme behaves incorrectly.

We’ll give it a try anyway:

🤔 Is the “beer” alcohol-free?

The answer according to the above programme is twice: “false”.
But the “gingerBeer” is non-alcoholic, isn’t it? What is going wrong here?

On the Beer object, the member “alcoholByVolume” is defined as a number. However, the ginger beer had not initialised the member “alcoholByVolume”. TypeScript (or JavaScript) returns “false” for the comparison “undefined < 0.5”.

“undefined” is not comparable to a number and always returns “false”.

Conclusion: Without “Strict mode”, the TypeScript compiler lacks the possibility to protect us software developers from unexpected errors due to missing definitions.

Example (fix) with Strict mode

If we had activated Strict mode, the IDE could have warned us of the compile error. If we had ignored this warning from the IDE, the compiler would have alerted us to the problem with an error message in the build process like below:

error TS2564: Property ‘alcoholByVolume’ has no initializer and is not definitely assigned in the constructor.

Finally, we would have adjusted the class with two changes:

(1) The member “alcoholByVolume” is extended with the type undefined. It thus becomes a so-called “optional member”.

(2) Before accessing “alcoholByVolume”, the method checks whether the member is undefined — if so, true is returned directly.

What’s Strict mode in TypeScript?

TypeScript itself defines enabling the “strict flags” as follows:

The strict flag enables a wide range of type checking behavior that results in stronger guarantees of program correctness.
source: https://www.typescriptlang.org/tsconfig#strict

For a detailed description check out the official documentation from mozilla.org.

How to activate Strict mode in TypeScript

Set the “strict” flag to “true” in the file “tsconfig.json” — this will activate all strict checks.

set the “strict”-flag to “true” in your “tsconfig.json” file

All strict-checks are listed on the following website: https://www.typescriptlang.org/tsconfig/#strict

  • noImplicitAny
  • noImplicitThis
  • strictNullChecks
  • strictPropertyInitialization
  • strictBindCallApply
  • strictFunctionTypes

By activating the Strict mode, all the above rules are activated.

Start using Strict mode

New Projects

It certainly makes sense to have “Strict mode” enabled for new TypeScript projects from the beginning. This saves a lot of time and hassle. In addition, the quality of software projects increases immensely and some software developers will also learn important JavaScript and TypeScript lessons. So it’s a first step in the right direction and it makes a benign programming language a bit more strict and thus more stable.

Existing Projects

In a project that was started some time ago, the developer is faced with a dilemma. On the one hand, you want the best possible quality — for example, by activating Strict mode. On the other hand, you don’t want to have to do any major refactorings. And actually everything looks quite harmless: Just setting a flag in a JSON file to true — where is the problem here?
If you have ever done it in a bigger project, you know what the problem is: The compiler does not build the project anymore. Not because of one error and not even because of a few errors, but probably rather because of a few hundred or thousand errors. Nobody has time and desire to solve all these chained problems and spend days initializing members, checking for types and much more.

A clever solution is nevertheless possible here, depending on the project, under the condition that the current project state is correct and under the contition that you’re working with a Git Repository:

  • (1) Activate Strict mode
    Set the “strict” flag to “true” in the file “tsconfig.json”
  • (2) Hack: Manually disable ts-checking for all files
    Add “// @ts-nocheck” to the first line of all *.ts files
    (this can be done automatically with a bash script or similar).
  • (3) Add a server hook
    Add a Git server hook on your repository which rejects future commits with file content “// @ts-nocheck

What exactly is happening?

Our basic idea behind this is to leave old as it is and develop new with the helpful and more stable strict-mode checking. By adding “// @ts-nocheck” (step 2) the TypeScript compiler ignores all checks of the respective file. Since we do this for all existing *.ts files, we have effectively enabled Strict mode and despite the thousands of errors, the build of the project continues to work. The server hook (step 3) ensures that no file containing our “// @ts-nocheck” hack can be pushed to the repository server in the future. So if you change something in an “old” file, you have to fix the single strict-mode issues, remove the hack on line 1 and then you can push.

Pro’s & Con’s

➕ Code quality is continuously improved
➕ activation of Strict mode possible
➖ more time needed for development during “mixed mode” (i.e. as long as files still have no ts-check by using “// @ts-nocheck”)

About this story

This article was published in German and translated into English. You can read my original article in German here. By the way: This is my first medium story.

I’m looking forward to the comments and I would also be interested to know how you migrated existing projects to Strict mode?

--

--

Benji

Software & Mobile — Engineer | interested in best practices and always looking for new challenges