Understanding strictNullCheck Option in tsconfig.json File

Updated: January 7, 2024 By: Guest Contributor Post a comment

Overview

TypeScript’s strictNullChecks option improves type safety by enforcing stricter type checking on variables that can be null or undefined. By understanding and implementing it, developers can avoid common pitfalls related to nullability and undefined values in their codebase.

Introduction to strictNullChecks

TypeScript enhances JavaScript by adding type annotations that enable developers to write safer and more predictable code. One of the compiler options TypeScript offers is strictNullChecks. When enabled, this option ensures that null and undefined have their own distinct types and are accounted for explicitly in the code.

Example:

let message: string;
message = 'Hello, TypeScript!'; // Okay
message = null; // Error when strictNullChecks is true
code>

By default, TypeScript treats null and undefined as assignable to anything. However, when strictNullChecks is true, these values are treated as separate types, and their assignments are strictly checked.

Configuring strictNullChecks

To enable strictNullChecks in your TypeScript project, include it in the tsconfig.json file:

{
  "compilerOptions": {
    "strictNullChecks": true
  }
}
code>

This change affects all the files in the project that are included in the TypeScript compilation context.

Handling Possible null Values

With strictNullChecks on, you cannot assign null to a variable unless you specify it in its type annotations:

let message: string | null; // message can be a string or null
message = null; // This is fine
message = 'Hello again'; // Also finecode

Additionally, when accessing properties or methods on a value, you must handle the possibility of null:

let message: string | null;
if (message) {
  console.log(message.trim()); // Only calls trim if message is not null
}
code>

This explicit handling forces you to write more robust code that acknowledges the potential for null values at compile time.

Working with Union Types and Nullability

Type safety extends into more complex structures, such as union types. When dealing with union types that include null, you must use type guards to access members safely:

function printLength(name: string | null) {
  if (name === null) {
    console.log('No name provided.');
  } else {
    console.log(name.length);
  }
}
code>

TypeScript only allows access to .length once it knows name is not null.

Advanced strictNullChecks Usage

In more advanced scenarios, developers can also leverage optional chaining (`?.`) and the nullish coalescing operator (`??`):

let message: string | null;
console.log(message?.trim() ?? 'Default message'); // Optional chaining and nullish coalescing in action
code>

This applies the trim method if message is non-null and returns ‘Default message’ when message is null.

Third-party Libraries and strictNullChecks

When using libraries that have their own definitions, bear in mind that they may not be compatible with strictNullChecks. This might require additional declaration merging or the use of non-null assertion operators to integrate them safely into a strictNullChecks enabled environment.

Pattern:Nullable Types and Default Values

Nullable types make the intention of allowing null explicit and can work together with default parameter values for functions:

function greeting(name: string | null = 'Guest') {
  return `Hello, ${name}!`;
}
// Both calls are valid:
greeting(); // Hello, Guest!
greeting('Alice'); // Hello, Alice!code

When no argument is provided, ‘Guest’ is used, and the function remains type safe.

Summary

The strictNullChecks compiler option in TypeScript increases your code’s type safety by making null handling explicit. It encourages better coding practices by having developers address the potential for null values. Note that legacy code bases may need significant refactoring to conform to these stricter rules, but the resulting code is typically more predictable and less error-prone.