TypeScript strictly typed: strict mode is not enough

Cyrille Tuzi
Jan 13 · 4 min read

Now that TypeScript has been widely adopted, it’s time to get serious and go to the end of the idea: fully statically typed code.

typescript-strictly-typed enables configurations for strictly typed TypeScript, ESLint or TSLint, and optionally Angular. But let’s explain first.

A French version of this article is available here.

Disclaimer

The purpose of this post is not to convince anyone about the benefits of TypeScript. Its target is developers who are already aware that now JavaScript is used to code applications (ie. is in charge of routing / navigation and templating / displaying the data), error checking is a requirement, not just a fancy option.

Also, I know that there are other kinds of errors than the ones which can be solved by static types, but it’s not the subject of this post either.

Level 0: JavaScript

In JavaScript, we are used to code in the nothingness: yeah, you know, all the times when the editor autocompletion is not suggesting anything, but we continue to write code, supposing it will magically work.

Code in the nothingness: ~50% (it’s just to give an idea, it’s not real metrics).

Level 1: TypeScript default mode

As TypeScript is just a superset of JavaScript (ie. not a different language, but standard native JavaScript optionally enhanced), by default, TypeScript will never ask to explicitly add types.

Instead, it will infer types as much as possible. Today’s TypeScript is very smart: let’s say it can infer ~80% of types.

But TypeScript is not a seer:

TypeScript can infer the type of the second parameter, thanks to the default value. But the first one will be any.

Code in the nothingness: ~20%.

Level 2: TypeScript strict mode

While not the default, the officially recommended way to work with TypeScript is in strict mode.

Strict mode activates 2 main compiler options:

  • noImplicitAny
  • strictNullChecks

Now, TypeScript will ask to tell when a value can be null (strictNullChecks), and when inference is not possible it will ask the type (noImplicitAny).

Note that TypeScript does not ask to add an explicit type for the second parameter: it’s still inferred. It’s why it’s “no implicit any”.

So going strict does not require a huge extra effort, it’s just about adding types in ~20% of the code.

Strict mode is enabled when creating:

  • a TypeScript project (tsc --init)
  • an Angular ≥ 9 app in strict mode (ng new --strict)
  • a React app (create-react-app --template typescript)
  • a Vue app (vue create with TypeScript option)

Code in the nothingness: seems to be 0%. But there is a catch: strict mode is not that strict.

Level 3: any is evil

The above code will compile, even in strict mode: explicit anys are still accepted by TypeScript.

Linters to the rescue. TSLint has the no-any rule. With ESLint and @typescript-eslint no-explicit-any rule:

All our code is now typed! Code in the nothingness: 0%.

But disabling all anys requires a little further knowledge of TypeScript than the basics.

unknown

Since TypeScript 3.0, when we really don’t know the type of a value, the right type is unknown, not any.

Contrary to any, which allows coding in the nothingness, unknown will make TypeScript remind us that the value is unknown and force us to check it.

Generics

Some other times, a type is known but variable: it’s called generics.

Bonus level: return types

While TypeScript will always infer the functions’ return type, it will do so based on the code. So we suppose, with extra confidence, that our code is doing what it is supposed to do.

Linters to the rescue, again. TSLint has the typedef rule with call-signature option. With ESLint and @typescript-eslint explicit-function-return-type rule:

Anyway, telling the type of functions’ parameters and return value should be the required minimal documentation.

Framework level: Angular strict

Some frameworks can add their own compilation step on top of TypeScript compilation. It’s the case of Angular, and so it has its own additional strict compiler options:

The strictTemplates flag is a new feature in Angular 9.

Automated configuration

To promote these good practices, I’ve created a lib which enables configurations for strictly typed TypeScript, ESLint or TSLint, and optionally Angular.

Just run npx typescript-strictly-typed in your project. Done!

Be sure to read the technical documentation first (requirements, known limitations…). If you have a problem with the lib, open an issue on GitHub (commenting here is not the right place to do it).

By the same author

My open source contributions are done on free time. So if your company earns money with them, it would be nice to consider becoming a sponsor.

Cyrille Tuzi

Written by

JavaScript and Angular trainer, PHP certified, @formationjs

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade