DEV Community

Cover image for What's new in TypeScript v4.4?
Ankit Tanna
Ankit Tanna

Posted on

What's new in TypeScript v4.4?

TypeScript 4.4 came out with a lot of performance update plus some improved type checking. As a developer, you may be excited about a few of the features that are listed below.

1. Control Flow Analysis of Aliased Conditions and Discriminants

Quite a bad-ass name for a feature 😄.

Its basically nothing but TypeScript becoming intelligent about the type of the variable if evaluated above.

Before

function foo(arg: unknown) {
  if (typeof arg === "string") {
    console.log(arg.toUpperCase());
}
Enter fullscreen mode Exit fullscreen mode

Now

function foo(arg: unknown) {
  const argIsString = typeof arg === "string";
  if (argIsString) {
    console.log(arg.toUpperCase());
  }
}
Enter fullscreen mode Exit fullscreen mode

TypeScript remembers that arg is evaluated and it's type is string. You dont need to perform the evaluation again and again.

2. Defaulting to unknown type in catch blocks

We use try-catch blocks to handle the mess that we create. But since the mess(dirty stuff needed to be done in catch block) can be generated from the different sources, the Error parameter in the catch block has to be kept loosely typed OR an implictly-any defined parameter.

Before

try {
  // Who knows what this might throw...
  executeSomeThirdPartyCode();
} catch (err) {
  // err: any
  console.error(err.message); // Allowed, because 'any'
  err.thisWillProbablyFail(); // Allowed, because 'any' :(
}
Enter fullscreen mode Exit fullscreen mode

Once you enable useUnknownInCatchVariables in your TSConfig file, the Error parameter in the catch block becomes of type any. And you will start seeing below errors:

Property 'message' does not exist on type 'unknown'.
Property 'name' does not exist on type 'unknown'.
Property 'stack' does not exist on type 'unknown'.
Enter fullscreen mode Exit fullscreen mode

After

try {
  // Who knows what this might throw...
  executeSomeThirdPartyCode();
} catch (err) {
  if (err instanceof Error) {
     console.error(err.message);
  }
}
Enter fullscreen mode Exit fullscreen mode

If you have a CustomError, you can create a class and make them extend with Error.

3. Exact Optional Property Types

This feature needs to be enabled in your TSConfig using the flag exactOptionalPropertyTypes. In JavaScript, reading a missing property in an object returns undefined.

Currently, if you define an interface like below:

interface Person {
  name: string;
  age?: number;
}
Enter fullscreen mode Exit fullscreen mode

The equivalent of the above interface was:

interface Person {
  name: string;
  age?: number | undefined;
}
Enter fullscreen mode Exit fullscreen mode

which meant that an object with a property age and it's value undefined were totally fine.

const p: Person = {
  name: "Daniel",
  age: undefined, // This is okay by default.
};
Enter fullscreen mode Exit fullscreen mode

but actually it is supposed to be interpreted as an object of type Person must contain name and another property age is optional but if it is present, age must be of type number.

With the exactOptionalPropertyTypes flag on, you can get be rest assured that if optional properties are a part of your object, they are assigned a correct type value.

PS - such things are good for type-geek devs like me! and you must enable it as well!

4. static blocks in classes

Static blocks in classes are a new feature of ECMAScript features that can help you write complex initialization logic for static members

class Foo {
    static count = 0;

    // This is a static block:
    static {
        if (someCondition()) {
            Foo.count++;
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Think of them as constructor for static properties 😄.

5. Inlay hints

This is kind of a good feature when you have a lengthy list of parameters in a function and you have a tough time remembering the sequence of it. Inlay hints display useful information like parameter names and return types in your code. You can think of it as a sort of friendly “ghost text”.

TS inlay hints image

6. No initializers for Abstract properties

Abstract properties cannot have initializers.

abstract class C {
  abstract prop = 1;
  //       ~~~~
  // Property 'prop' cannot have an initializer because it is marked abstract.
}
Enter fullscreen mode Exit fullscreen mode

7. Performance improvements and other goodies

There have been many behind the scenes improvement like below:

  • Faster declaration emits (symbols of classes that are accessible)
  • Faster path normalization (basically translating ../../ --> to a proper path)
  • Faster incremental builds if --strict flag is on. This will certainly give you nightmares in your initial days and if your project is big, it will take some amount of time to clear up this mess!
  • Faster source map generation (Do leave in the comments, do we need source maps now?)
  • Better spelling suggestions
  • Auto-imports showing true/complete path

I hope you enjoyed this brief read about TypeScript and it's new features. If you are geeky and are not able to sleep, you can go and read the TypeScript Release Notes.

I run a small YouTube channel named EverydayJavaScript. Please do subscribe to it if you haven't fallen asleep reading the release notes!

Happy TypeScript-ing!

Oldest comments (5)

Collapse
 
vineyrawat profile image
Viney Rawat

That's why I love 💕 Typescript 👍

Collapse
 
samuelsonvs profile image
Samuelsonvs • Edited

Example second of can be
catch(err ) {
console.error((err as Error).message);
}

Collapse
 
ankittanna profile image
Ankit Tanna

Yeah even this can be used. But to be honest, I hate type castings using 'as' keyword.

Collapse
 
dtiziani profile image
Tizi

if so, then it's not worth using useUnknownInCatchVariables. Using 'as' this way, you're not guarding the type, only forcing it

Collapse
 
ankittanna profile image
Ankit Tanna

yup I hate the as keyword typecasting.