AngularConcepts of programming languagesTypeScript

Angular 6 Brings TypeScript 2.7 Bringing Improved Null-Safety

The web is full of articles praising the improvements of Angular 6, such as library support (great!) and Angular Elements (even greater!). One small change usually passes by as a mere side-remark. But it’s a useful change, too. Angular 6 now officially supports TypeScript 2.7. That, in turn, is a major step forward for our project, because TypeScript 2.7 fills a nasty gap concerning null-safety.

You know, I played benevolent dictator, decreeing that null values need to be declared explicitly. In other words, I activated the flag strictNullChecks in the tsconfig.json file.

Unfortunately, I wasn’t prepared for the reaction. It took me a lot of talking to convince the team to keep the setting. Actually, I coaxed them to wait until Angular 6, which is “about to come out every day”. Adding insult to injury, Angular 6 took several weeks more than I expected, but now it’s there.

What’s the problem?

My team observed two problems. One is a weird failure of type inference involving closures. No idea what’s happening there. I just hope it’s a bug of the TypeScript compiler which is going to be solved one day or another.

But it’s the second problem I want to blog about. Many attributes of a component or a service are declared without an initial value. But from a practitioner’s point of view, this attribute is never null. It’s initialized just a bit later – in the constructor of the class, or in the ngOnInit() method:

export class NgxPdfViewerComponent {
  @Input()
  private srcFile: string;

  constructor() { }
}

This example shows a similar scenario. If you forget to provide the source file of the PDF viewer component, the result is catastrophic. There’s no way the user or the programmer can ignore it. So you can safely assume that the attribute srcFile is neither null nor undefined.

Adding a simple exclamation mark

But TypeScript doesn’t know that. Since TypeScript 2.7, you can advise the compiler to ignore the missing default value. In other words, you can tell it “I know better than you”. It goes without saying that this imposes the burden to deliver on you.

You do so by adding an exclamation mark. The syntax resembles the Elvis operator:

export class NgxPdfViewerComponent {
  @Input()
  private srcFile!: string;

  constructor() { }
}

Now the problem is solved. The compiler stops complaining when you’re using the attribute. The responsibility to make sure it’s neither null nor undefined is up to you again. But that’s what you readily accept when you add the “I know for sure!” operator.

Wrapping it up

In a way, the solution is anticlimactic: adding a simple exclamation mark solves all the trouble. However, it was a trouble disturbing me a lot. Before the advent of TypeScript 2.7, we had to add a lot of string | null or even string | undefined to our declarations. That, in turn, forced us to care about all these special cases time and again. It’s a great relief that TypeScript finally adds the “I know for sure!” operator. By the way, this may be a useful aide-memoire: “I know for sure!” ends with an exclamation mark, too.