Strict Checks
We recommend using the compiler option strict
to opt-in to every possible improvement as they are built.
TypeScript supports a wide spectrum of JavaScript patterns and defaults to allowing for quite a lot of flexibility in accommodating these styles. Often the safety and potential scalability of a codebase can be at odds with some of these techniques.
Because of the variety of supported JavaScript, upgrading to a new version of TypeScript can uncover two types of errors:
- Errors which already exist in your codebase, which TypeScript has uncovered because the language has refined its understanding of JavaScript.
- A new suite of errors which tackle a new problem domain.
TypeScript will usually add a compiler flag for the latter set of errors, and by default these are not enabled.
Always Strict - alwaysStrict
Ensures that your files are parsed in the ECMAScript strict mode, and emit “use strict” for each source file.
ECMAScript strict mode was introduced in ES5 and provides behavior tweaks to the runtime of the JavaScript engine to improve performance, and makes a set of errors throw instead of silently ignoring them.
No Implicit Any - noImplicitAny
In some cases where no type annotations are present, TypeScript will fall back to a type of any
for a variable when it cannot infer the type.
This can cause some errors to be missed, for example:
Try
functionfn (s ) {// No error?console .log (s .subtr (3));}fn (42);
Turning on noImplicitAny
however TypeScript will issue an error whenever it would have inferred any
:
Try
functionParameter 's' implicitly has an 'any' type.7006Parameter 's' implicitly has an 'any' type.fn () { s console .log (s .subtr (3));}
Recommended:
True
Default:
false
, unlessstrict
is setRelated:
No Implicit This - noImplicitThis
Raise error on ‘this’ expressions with an implied ‘any’ type.
For example, the class below returns a function which tries to access this.width
and this.height
– but the context for this
inside the function inside getAreaFunction
is not the instance of the Rectangle.
classRectangle {width : number;height : number;
constructor(width : number,height : number) {this.width =width ;this.height =height ;}Try
getAreaFunction () {return function () {return'this' implicitly has type 'any' because it does not have a type annotation.this .width *this .height ;
'this' implicitly has type 'any' because it does not have a type annotation.2683
2683'this' implicitly has type 'any' because it does not have a type annotation.
'this' implicitly has type 'any' because it does not have a type annotation.};}}
Strict - strict
The strict
flag enables a wide range of type checking behavior that results in stronger guarantees of program correctness. Turning this on is equivalent to enabling all of the strict mode family options, which are outlined below. You can then turn off individual strict mode family checks as needed.
Future versions of TypeScript may introduce additional stricter checking under this flag, so upgrades of TypeScript might result in new type errors in your program. When appropriate and possible, a corresponding flag will be added to disable that behavior.
Recommended:
True
Default:
false
Related:
alwaysStrict
,strictNullChecks
,strictBindCallApply
,strictFunctionTypes
,strictPropertyInitialization
,noImplicitAny
,noImplicitThis
Released:
Strict Bind Call Apply - strictBindCallApply
When set, TypeScript will check that the built-in methods of functions call
, bind
, and apply
are invoked with correct argument for the underlying function:
// With strictBindCallApply onfunctionfn (x : string) {returnparseInt (x );}
constn1 =fn .call (undefined , "10");Try
constArgument of type 'boolean' is not assignable to parameter of type 'string'.2345Argument of type 'boolean' is not assignable to parameter of type 'string'.n2 =fn .call (undefined ,false );
Otherwise, these functions accept any arguments and will return any
:
// With strictBindCallApply offfunctionfn (x : string) {returnparseInt (x );}Try
// Note: No error; return type is 'any'constn =fn .call (undefined , false);
Strict Function Types - strictFunctionTypes
When enabled, this flag causes functions parameters to be checked more correctly.
Here’s a basic example with strictFunctionTypes
off:
functionfn (x : string) {console .log ("Hello, " +x .toLowerCase ());}
typeStringOrNumberFunc = (ns : string | number) => void;Try
// Unsafe assignmentletfunc :StringOrNumberFunc =fn ;// Unsafe call - will crashfunc (10);
With strictFunctionTypes
on, the error is correctly detected:
functionfn (x : string) {console .log ("Hello, " +x .toLowerCase ());}
typeStringOrNumberFunc = (ns : string | number) => void;
// Unsafe assignment is preventedletType '(x: string) => void' is not assignable to type 'StringOrNumberFunc'.: func StringOrNumberFunc =fn ;Types of parameters 'x' and 'ns' are incompatible.
Type 'string | number' is not assignable to type 'string'.
Type 'number' is not assignable to type 'string'.2322Type '(x: string) => void' is not assignable to type 'StringOrNumberFunc'.
Types of parameters 'x' and 'ns' are incompatible.
Type 'string | number' is not assignable to type 'string'.
Type 'number' is not assignable to type 'string'.
Try
During development of this feature, we discovered a large number of inherently unsafe class hierarchies, including some in the DOM. Because of this, the setting only applies to functions written in function syntax, not to those in method syntax:
typeMethodish = {func (x : string | number): void;};
functionfn (x : string) {console .log ("Hello, " +x .toLowerCase ());}Try
// Ultimately an unsafe assignment, but not detectedconstm :Methodish = {func :fn ,};m .func (10);
Strict Null Checks - strictNullChecks
When strictNullChecks
is false
, null
and undefined
are effectively ignored by the language. This can lead to unexpected errors at runtime.
When strictNullChecks
is true
, null
and undefined
have their own distinct types and you’ll get a type error if you try to use them where a concrete value is expected.
For example with this TypeScript code, users.find
has no guarantee that it will actually find a user, but you can write code as though it will:
declare constloggedInUsername : string;
constusers = [{name : "Oby",age : 12 },{name : "Heera",age : 32 },];Try
constloggedInUser =users .find ((u ) =>u .name ===loggedInUsername );console .log (loggedInUser .age );
Setting strictNullChecks
to true
will raise an error that you have not made a guarantee that the loggedInUser
exists before trying to use it.
declare constloggedInUsername : string;
constusers = [{name : "Oby",age : 12 },{name : "Heera",age : 32 },];Try
constloggedInUser =users .find ((u ) =>u .name ===loggedInUsername );Object is possibly 'undefined'.2532Object is possibly 'undefined'.console .log (. loggedInUser age );
The second example failed because the array’s find
function looks a bit like this simplification:
ts
// When strictNullChecks: truetype Array = {find(predicate: (value: any, index: number) => boolean): S | undefined;};// When strictNullChecks: false the undefined is removed from the type system,// allowing you to write code which assumes it always found a resulttype Array = {find(predicate: (value: any, index: number) => boolean): S;};
Strict Property Initialization - strictPropertyInitialization
When set to true, TypeScript will raise an error when a class property was declared but not set in the constructor.
classUserAccount {name : string;accountType = "user";
Property 'email' has no initializer and is not definitely assigned in the constructor.2564Property 'email' has no initializer and is not definitely assigned in the constructor.: string; address : string | undefined;Try
constructor(name : string) {this.name =name ;// Note that this.email is not set}}
In the above case: