TypeScript - (tsconfig) Strict Checks

#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.

Default:
false, unless strict is set
Released:
2.1
# 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:

function fn(s) {
  // No error?
  console.log(s.subtr(3));
}
fn(42);Try
Turning on noImplicitAny however TypeScript will issue an error whenever it would have inferred any:

function fn(s) {
Parameter 's' implicitly has an 'any' type.
  console.log(s.subtr(3));
}Try
Recommended:
True
Default:
false, unless strict is set
# 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.

class Rectangle {
  width: number;
  height: number;

  constructor(width: number, height: number) {
    this.width = width;
    this.height = height;
  }

  getAreaFunction() {
    return function () {
      return this.width * this.height;
'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.
    };
  }
}Try
Recommended:
True
Default:
false, unless strict is set
Released:
2.0
# 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:
strictBindCallApply, strictFunctionTypes, strictPropertyInitialization
Released:
2.3
# 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 on
function fn(x: string) {
  return parseInt(x);
}

const n1 = fn.call(undefined, "10");

const n2 = fn.call(undefined, false);
Argument of type 'boolean' is not assignable to parameter of type 'string'.
Try
Otherwise, these functions accept any arguments and will return any:

// With strictBindCallApply off
function fn(x: string) {
  return parseInt(x);
}

// Note: No error; return type is 'any'
const n = fn.call(undefined, false);Try
Recommended:
True
Default:
false, unless strict is set
Released:
3.2
# Strict Function Types - strictFunctionTypes
When enabled, this flag causes functions parameters to be checked more correctly.

Here’s a basic example with strictFunctionTypes off:

function fn(x: string) {
  console.log("Hello, " + x.toLowerCase());
}

type StringOrNumberFunc = (ns: string | number) => void;

// Unsafe assignment
let func: StringOrNumberFunc = fn;
// Unsafe call - will crash
func(10);Try
With strictFunctionTypes on, the error is correctly detected:

function fn(x: string) {
  console.log("Hello, " + x.toLowerCase());
}

type StringOrNumberFunc = (ns: string | number) => void;

// Unsafe assignment is prevented
let func: StringOrNumberFunc = fn;
Type '(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:

type Methodish = {
  func(x: string | number): void;
};

function fn(x: string) {
  console.log("Hello, " + x.toLowerCase());
}

// Ultimately an unsafe assignment, but not detected
const m: Methodish = {
  func: fn,
};
m.func(10);Try
Recommended:
True
Default:
false, unless strict is set
Released:
2.6
# 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 const loggedInUsername: string;

const users = [
  { name: "Oby", age: 12 },
  { name: "Heera", age: 32 },
];

const loggedInUser = users.find((u) => u.name === loggedInUsername);
console.log(loggedInUser.age);Try
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 const loggedInUsername: string;

const users = [
  { name: "Oby", age: 12 },
  { name: "Heera", age: 32 },
];

const loggedInUser = users.find((u) => u.name === loggedInUsername);
console.log(loggedInUser.age);
Object is possibly 'undefined'.
Try
The second example failed because the array’s find function looks a bit like this simplification:

// When strictNullChecks: true
type 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 result
type Array = {
  find(predicate: (value: any, index: number) => boolean): S;
};
Recommended:
True
Default:
false, unless strict is set
Released:
2.0
# 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.

class UserAccount {
  name: string;
  accountType = "user";

  email: string;
Property 'email' has no initializer and is not definitely assigned in the constructor.
  address: string | undefined;

  constructor(name: string) {
    this.name = name;
    // Note that this.email is not set
  }
}Try
In the above case:

this.name is set specifically.
this.accountType is set by default.
this.email is not set and raises an error.
this.address is declared as potentially undefined which means it does not have to be set.
Default:
false, unless strict is set
Released:
2.7

Comments

Popular posts from this blog

Today Walkin 14th-Sept

Spring Elasticsearch Operations

Hibernate Search - Elasticsearch with JSON manipulation