DEV Community

Andy Li
Andy Li

Posted on

"Strict Mode" TypeScript config options

You can enable the "strict mode" in TypeScript by using the strict option. (BTW, TypeScript is the superset of the .. the most popular programming language in the world~)

For example, here's a sample tsconfig.json file where the strict option is set to true:

{
  "compilerOptions": {
    "target": "es5",
    "lib": [ "esnext" ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "strict": true, // HERE
    "module": "esnext",
    "moduleResolution": "node",
    "isolatedModules": true,
    "noEmit": true
  },
  "include": [
    "src"
  ]
}
Enter fullscreen mode Exit fullscreen mode

This article isn't about TypeScript for absolute beginners, this is for intermediate users. However, we are not going to cover all of the configuration options, we're just going to talk about one, the strict option.

So what's strict?

The strict option will subject your code to stricter rules in terms of static type checking. Stricter means safer, so it's a good thing. The special thing about this strict option is that, it's actually a shortcut for a set of seven different options.

The seven options are:

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

So yeah, I lied. We're not just going to talk about one configuration option, we're going to talk about seven of them!!!

Before we begin, replace this in the config:

  "strict": true,
Enter fullscreen mode Exit fullscreen mode

with these guys:

  "noImplicitAny": true,
  "noImplicitThis": true,
  "alwaysStrict": true,
  "strictBindCallApply": true,
  "strictNullChecks": true,
  "strictFunctionTypes": true,
  "strictPropertyInitialization": true,
Enter fullscreen mode Exit fullscreen mode

We are doing it this way so that you can easily toggle each individual one on and off to see its effect.

Now let's begin!

1. noImplicitAny

It makes sure that you can't just use "JavaScript," it forces you to use "TypeScript."

So you can't just do this:

function double(x){
  return x + x
}
Enter fullscreen mode Exit fullscreen mode

tsc or VS Code will give you an error.

x will be typed any, and it's implicit (implicit means you didn't assign it yourself), that goes against the noImplicitAny rule.

To fix this, you should give it a type, any is fine too:

function double(x: any){
  return x + x
}
Enter fullscreen mode Exit fullscreen mode

Since now it's explicit, not implicit.

If you're fine with implicit any, you can just set this option to false.

2. noImplicitThis

With this option, you can't use this directly like this inside a function:

function print(x){
  console.log(this, x)
}
Enter fullscreen mode Exit fullscreen mode

So what's wrong with this?

this is typed any implicitly.

So to fix this problem, we have to make this the first argument:

function print(this, x){
  console.log(this, x)
}
Enter fullscreen mode Exit fullscreen mode

Don't worry, you can still use the function normally like this:

print('Hello')
Enter fullscreen mode Exit fullscreen mode

No need to pass in the this reference yourself.

3. alwaysStrict

You know how ES5 allows you to write code in a strict mode by placing a string on top of a file:

"use strict";
Enter fullscreen mode Exit fullscreen mode

Turning on this option will make every compiled .js file to have this as the first line.

4. strictBindCallApply

Let's say you have a function like this:

function foo(a: number, b: string) {
  console.log(a + b);
}
Enter fullscreen mode Exit fullscreen mode

Calling the function like this will give you an error:

foo(1, 2) // error
Enter fullscreen mode Exit fullscreen mode

Because the second variable has to be a string.

But if you're setting the strictBindCallApply option to false, you can call the function like this without error:

foo.apply(undefined, [ 1, 2 ])
Enter fullscreen mode Exit fullscreen mode

This is a loophole, and this loophole can make your code buggy. The strictBindCallApply option is used for fixing this loophole.

By setting strictBindCallApply to true, you get the helpful type checking error again:

foo.apply(undefined, [ 1, 2 ]) // error
Enter fullscreen mode Exit fullscreen mode

5. strictNullChecks

This option makes sure that you can't assign null or undefined to a variable of an existing type:

let num = 1;
num = null; // error
Enter fullscreen mode Exit fullscreen mode

So in the above code, the variable is inferred to be a number type, so you can't reassign it with null.

6. strictFunctionTypes

This one is a bit elaborate, I'll have another article talking about this specifically. But in short, it's about making the function types contravariant instead of the default bivariant behavior.

7. strictPropertyInitialization

This is an option for creating a class. Declared members of a class need to be assigned with values, either in the constructor or directly in the declaration.

class Foo {

  bar: string
  bar2: number // error

  constructor(){
    this.bar = 'Hello'
  }
}
Enter fullscreen mode Exit fullscreen mode

bar doesn't raise an error because it's been initialized with 'hello' in the constructor, but bar2 isn't initialized.

Bottom Line

Strict TypeScript is good, and it makes sense. If you want a simpler life, just set the strict option to true and fix the any type error raised by VS Code.

Top comments (2)

Collapse
 
reubence profile image
Reuben Rapose

Great Summary!

Collapse
 
arudope profile image
Aldo Ortiz

I don't learn TS yet, but I'm very interested in learning it after I spend more time practicing my JavaScript skills.