TypeScript strictly typed: strict mode is not enough

Cyrille Tuzi
3 min readJan 13, 2020

--

NOTE: I wrote a new posts series, far more complete, about this topic.

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.

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 app (ng new)
  • 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. 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.

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:

Angular Schematics

Also an Angular user? If you want to save time when creating new components, services and else, give a try to my Angular Schematics extension for Visual Studio Code, installed nearly 1 million times.

--

--

Cyrille Tuzi

JavaScript and Angular trainer and developer, PHP certified,