StrictNullChecks in TypeScript

Learn via video courses
Topics Covered

Overview

Null denotes a value that is either empty or does not exist. It's on purpose that there's nothing of worth here. TypeScript does not make variables null by default.

Unassigned variables or variables declared without being initialized are 'undefined' by default. To make a variable null, we must assign it the value Null. Typescript utilizes null to denote variables that have no values or have no values set to them.

Introduction

In JavaScript, use the typeof operator to determine the datatype of a variable. The typeof operator is a unary operator that returns a string that indicates the type of the unevaluated operand. The null value denotes the lack of an object value. Use the following code to determine the typeof null.

Output :

In JavaScript, you can see that null is an object. Null, like String, Number, Boolean, undefined, and Symbol, is a primitive value in JavaScript. Unfortunately, the typeof operator returns "object" when called on null data. We are talking so much about Null, so let’s see what exactly is this Null.

What is Null?

The value null denotes the deliberate lack of any object value. It is a primitive value in JavaScript.

The JavaScript primitive type null signifies an intended lack of a value, it is typically used to signal that a variable has been declared but has yet to be assigned a value. This differs from the related primitive value undefined, which is an inadvertent lack of any object value.

This is because a variable that has been declared but has not been assigned a value is undefined, not null. Unfortunately, when called on a null value, typeof returns object due to a historical flaw in JavaScript that will never be corrected. This means that typeof cannot be used to check for null because the value of the Null state is falsy.

Javascript Null Check

The easiest approach to check for null is to remember that under conditionals or when coerced to a boolean value, null evaluates to false : Of course, this doesn't distinguish null from the other false values. In JavaScript, use the equality operators == or === to check for a null value. Except for undefined and null, the null value is not roughly equivalent to any of the other false values.

Output :

The output shows that null is only weakly equivalent to undefined and itself. It is not equal to any other erroneous value.

So, if you run into a use case where you want to verify if the variable has any value at all before processing it, use == null to check for null or undefined.

Strict Equality Using ===

In JavaScript, utilize the triple equality operator(===) to check for null values.

Output :

As you can see, checking null === undefined yields false. That is, if we carefully compare both values, they are not the same. If you want to check for a null value explicitly, just use the triple equality operator (===). In JavaScript, it is the preferred operator for checking null values. To explicitly check if the value is null, use the triple equality operator. There is nothing wrong with it, like me, many JavaScript developers desire everything to be clear to be right.

JavaScript Object is() Method

Javascript Object is() is a built-in function that determines whether two values are the same. In how it tests for NaN and negative zero -0 values, the ES2015 method Object is() varies from the strict === and loose == equality operators.

Object is() behaves similarly to the (===) triple equality operator when checking for null values.

Output :

If you wish to verify whether a variable is null or undefined manually, use the JavaScript Object is() function. When it comes to comparing null and undefined, the Object is() function is the same as ===.

In JavaScript, use the triple-equals operator (===) or the Object is() function to check for null. Use the triple equality operator or the Object is() function to distinguish between null and undefined.

StrictNullChecks

strictnullchecks-introduction

When strictNullChecks is set to false, the language essentially ignores null and undefined. This might result in unexpected failures during runtime.

When StrictNullChecks is set to true, null and undefined have their separate types and using them when a concrete value is expected results in a type error.

For example, users. find in TypeScript offers no assurance that it will discover a user, but you may write code as if it will :

Output :

Setting StrictNullChecks to true will result in an error since you have not ensured that the loggedInUser exists before attempting to use it.

Output :

Note : It would be wonderful if enabled because Typescript adds stringent null checks for dynamic runtime issues. In vs code, use the following syntax to activate it.

StrictNullCheck in Typescript

StrictNullChecks in TypeScript adds tougher type checks for null and undefined values. TypeScript 2.0 introduces this option. We activate it by adding strictNullChecks: true to the tsconfig.json file, which assures that the compiler will throw an error if we assign Null and Undefined to other types.

Strict Null Checks

Null and Undefined are special values that signify a value that does not exist. We may assign them to any other type, such as integers, strings, and so on. In JavaScript, the such assignment has been the source of many problems, such as Uncaught TypeError: Cannot access property 'propertyName' of undefined/null, and so on. When we try to access a property on an undefined or null object, this error is issued.

Prior to version 2.0, TypeScript never informed us when we attempted to access a property of a null or undefined object. In the following example, giving null to the sayHi method results in no compile-time errors. When you run the code, however, you will receive a (Cannot read properties of null) error.

Enabling StrictNullChecks

To enable StrictNullChecks, edit tsconfg.sys and change the compilerOptions to strictNullCheck: true.

If you set this to true, you'll get a type error if you try to use null or undefined in places where Typescript expects a concrete type.

For instance, code from the preceding section causes a compiler error. The argument of type 'null' cannot be assigned to a parameter of type. This allows us to repair the mistake without having to wait for the code to execute and crash.

Null & Undefined under StrictNullChecks

  • The undefined may only be assigned to any, void, and undefined.
  • Except for never, any, and undefined, nothing may be assigned to undefined.
  • null is only assignable to any & null
  • Nothing may be assigned to null except another null.

The section that follows contains some of the most common issues that occur when stringent null checks are enabled, as well as remedies to them.

Assigning Null or Undefined

We cannot assign null or undefined other data types when StrictNullChecks is set to true. However, this is not feasible in practice. We cannot assign null or undefined to numberVar in the following example.

We must explicitly set a variable to accept null or undefined values. We can accomplish this by defining a union type.

When passing null as an argument to a function, you may utilize a similar method.

You may also use the optional parameter? to pass undefined.

Object is Possibly Null

If you provide null or undefined to a function and then use it, you will get the Object is possibly null or Object is maybe undefined error.

For instance, the following code generates a compiler error at the console.log command. Because nulls are permitted, the TypeScript compiler believes that the p might be null.

There are many ways to solve the above error, out of which a few good ones are :

  • Use it to check for null
  • Non-null assertion operator "!"
  • Nullish Coalescing operator
  • Optional Chaining using "?"

Use if to check for null :
If the condition is null or undefined. Because we tested for null in the if condition, the p will never be null in the otherwise sentence. The TypeScript compiler is intelligent enough to recognize this and does not raise any errors. This is referred to as Type Guards.

Non-null assertion operator "!" :
TypeScript 2.0 introduces the ! non-null assertion operator. This operator is used to tell the Type checker that its operand is not null or undefined. The code immediately following p! informs the compiler that p is neither null nor undefined. As a result, the compiler generates no errors.

However, if you pass a null object, you will receive a run time error. As a result, use this operator only if you are confident that it will never be null or undefined.

Nullish Coalescing operator :
The nullish coalescing operator (??) is a two-argument logical operator. When the left-hand side operand is null or undefined, it returns the right-hand side operand. Otherwise, it returns its operand from the left side.

If the expression is null, the Nullish Coalescing can be utilized to produce a default value. If foo is null (or undefined), the code will return bar(), otherwise, it will return foo.

Optional Chaining using "?" :
When you utilize optional chaining, the run time will stop the execution if it meets a null or undefined value and returns undefined. In the code below, for example, if foo is specified, then bar.baz() is calculated. However, if foo is null or undefined, the run time will terminate the program and return undefined.

Hence When we pass null in the following code, no errors are thrown. When p is null, however, p?.name yields the value undefined.

Type Guards to Prevent Compiler Error

type-guards-to-prevent-compiler-error

A type guard is a TypeScript mechanism for determining the type of a variable, typically within a conditional block. Type guards are regular functions that take a type and return a boolean indicating whether or not it can be reduced down to something more particular.

Type guards provide the unique characteristic of ensuring that the value checked is of a specific type based on the boolean returned. TypeScript employs built-in JavaScript operators such as typeof, instanceof, and the in operator to determine if an object includes a property. Type guards allow you to tell the TypeScript compiler to infer a given type for a variable in a specific context, guaranteeing that an argument's type is what you say it is.

Type guards, which are similar to feature detection in that they allow you to detect the correct methods, prototypes, and attributes of a value, are often used for narrowing a type. As a result, you can quickly determine how to handle that data.

A type guard can be used in five different ways :

  • The instanceof keyword
  • The in keyword
  • The typeof keyword
  • Custom type guard with predicate
  • Equality narrowing type guard

The "instanceof" Type Guard

The built-in type guard instanceof may be used to determine whether a value is an instance of a particular function Object() function or class. We may use this type of guard to determine the type of instance type by testing if an object or value is derived from a class.

The following is the fundamental syntax for the instanceof type guard :

In the following example, we observe an instanceof type guard :

Output :

Explanation :
Since they both implement the Institute interface, the getRandomInstitute method above returns either a JEE or a NEET. JEE and NEET function Object() signatures differ, and the instanceof type guard examines both function Object() signatures to effectively identify the type.

The "typeof" Type Guard

The typeof type guard is used to identify a variable's type. The sort of guard is believed to be extremely restricted and shallow. It can only determine the JavaScript-recognized types :

  • Boolean
  • number
  • string
  • undefined
  • bigint
  • function
  • symbol

The typeof type guard just returns objects for everything, not on this list. The typeof type guard can be expressed in two ways :

The typename parameter can be a number, string, symbol, or boolean.

Let's understand it with the help of an example EmployeeId has a string | number type union parameter entry in the example below. If the variable is a string, it prints Employee; if it is a number, it prints Id. The typeof type guard assists us in determining the type of x :

Output :

The "in" Type Guard

The in type guard determines if an object has a specific attribute and uses its attributes to distinguish between various types. It generally returns a boolean indicating whether or not the property exists in that object. It is utilized for its narrowing capabilities as well as to check for browser compatibility.

The following is the fundamental syntax for the in type guard :

In the following example, the in type guard determines if the property home exists. When it exists, the boolean true is returned, when it does not exist, the boolean false is returned.

Output :

Custom Type Guard with Predicate

Typically, the most powerful approach for employing type guards is to create a custom type guard. There are no restrictions on what you may check when you write your custom type guard. However, if the custom type guard is written wrong, it might cause a slew of problems. As a result, accuracy is essential.

The following is an example of a custom-type guard :

Output :

Conclusion

  • TypeScript includes a robust framework for dealing with null or undefined values.
  • Null and undefined handling is disabled by default, but they may be enabled by setting 'StrictNullChecks' to true.
  • Null is the purposeful lack of a value (null is explicit), Null must be set to a variable, and The typeof null is an object.
  • Use the triple equals operator (===) or the Object is() function to check for null or to distinguish between null and undefined.
  • We also discussed four alternative approaches to dealing with the reoccurring 'NULL' problem.
  • Type guards in TypeScript are useful for ensuring the value of a type and improving overall code flow.
  • There are several Type Guards, but the 'instanceof', 'typeof', and 'in' types are the most often used.
  • In this article, we looked at all three useful type guards in TypeScript and looked at several examples to understand how they work.