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"
]
}
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,
with these guys:
"noImplicitAny": true,
"noImplicitThis": true,
"alwaysStrict": true,
"strictBindCallApply": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictPropertyInitialization": true,
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
}
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
}
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)
}
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)
}
Don't worry, you can still use the function normally like this:
print('Hello')
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";
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);
}
Calling the function like this will give you an error:
foo(1, 2) // error
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 ])
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
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
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'
}
}
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)
Great Summary!
I don't learn TS yet, but I'm very interested in learning it after I spend more time practicing my JavaScript skills.