Angular & TypeScript: Writing Safer Code with strictNullChecks

On May 4, Angular 4.1.1 was released. This release fulfils a promise already made for Angular 4.1: Adding support for TypeScript’s strictNullChecks compiler option added in TypeScript 2.0.

Strict Null Checking = Safer Code

This transpiler flag enables us to write safer code. TypeScript with strict null checking enabled feels even more comfortable for developers with a static-typed language background. Without strict null checking, assigning null or undefined for instance to a variable of type number is perfectly possible:

// OK
const age: number = 24;
const age: number = null;

For JavaScript developers, this is absolutely clear as JavaScript doesn’t perform any type checking on variable assignments. But this seems quite odd to Swift or C# developers who are used to the concepts of optionals or nullables, respectively. Let’s look at a sample from C#:

// OK
int age = 24;
int? age = 24;
int? age = null;

// error CS0037: Cannot convert null to 'int' because it is a non-nullable value type
int age = null;

Strict null checking allows us to opt-in to the exact same behaviour: The equivalent of the int? nullable type from C# shown above would be the number | null union type. Now let’s see the behaviour of the TypeScript compiler with strictNullChecks turned on:

// OK
const age: number = 24;
const age: number | null = 24;
const age: number | null = null;
const age: number | undefined = undefined;

// TS2322: Type 'null' is not assignable to type 'number'.
const age: number = null;

Please note that in contrast to optionals and nullables, there are no measures or methods for unwrapping the values in a safe manner. Uninitialised variables will still be undefined; and as TypeScript’s type checking is a development and transpile-time feature only, during the execution of the originating JavaScript anything else could be assigned as well.

However, this behaviour is much more what developers with a static-typed language background would expect. Strict null checking helps eliminating careless mistakes and strengthens the code base by making the occurrence of null values far more explicit—which is an inherent feature of the Swift language.

How to Opt-in

In order to opt-in to the new strict null checking, make sure to upgrade to Angular 4.1.1 and thus TypeScript 2.1 (or later) and add the following line to your tsconfig.json:

{
  "compileOnSave": false,
  "compilerOptions": {
    "outDir": "./dist/out-tsc",
    "baseUrl": "src",
    "sourceMap": true,
    "declaration": false,
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "strictNullChecks": true,
    "target": "es5",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2016",
      "dom"
    ]
  }
}

You may have to adjust existing type definitions where necessary. The TypeScript compiler will point you to the places in your code where changes have to be made. Please also note that every third-party library in use has to support strictNullChecks.

(Little) Effort, Great Effect

All in all, strict null checking can prevent careless mistakes and small bugs which are typically hard to identify. By making the occurrence of null/undefined values far more explicit, it strengthens the application’s code base—an ideal choice especially for large-scale applications. Opting-in is an easy process for greenfield projects starting with Angular 4.1.1 or later: just add the line from above to your tslint.json. Brownfield projects additionally have to be migrated to this Angular version first, type declarations might have to be modified at a reasonable effort, depending on the project.

Published by

Christian Liebel

Hey there! I am Christian Liebel from Leimersheim, Germany. I work as a consultant at Thinktecture and I am their representative at W3C. Web app development with Angular and .NET is our day-to-day business. Feel free to contact me anytime.