What's new in TypeScript v4.4?
Tags: typescript, javascript, webdev, angular
Published: 2021-09-12 17:47:42

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 :smile:.

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

###Before
```javascript
function foo(arg: unknown) {
  if (typeof arg === "string") {
    console.log(arg.toUpperCase());
}
```

###Now
```javascript
function foo(arg: unknown) {
  const argIsString = typeof arg === "string";
  if (argIsString) {
    console.log(arg.toUpperCase());
  }
}
```

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
```javascript
try {
  // Who knows what this might throw...
  executeSomeThirdPartyCode();
} catch (err) {
  // err: any
  console.error(err.message); // Allowed, because 'any'
  err.thisWillProbablyFail(); // Allowed, because 'any' :(
}
```

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:
```javascript
Property 'message' does not exist on type 'unknown'.
Property 'name' does not exist on type 'unknown'.
Property 'stack' does not exist on type 'unknown'.
```

###After
```javascript
try {
  // Who knows what this might throw...
  executeSomeThirdPartyCode();
} catch (err) {
  if (err instanceof Error) {
     console.error(err.message);
  }
}
```

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:
```javascript
interface Person {
  name: string;
  age?: number;
}
```

The equivalent of the above interface was:
```javascript
interface Person {
  name: string;
  age?: number | undefined;
}
```
which meant that an object with a property **age** and it's value **undefined** were totally fine.

```javascript
const p: Person = {
  name: "Daniel",
  age: undefined, // This is okay by default.
};
```

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
```javascript
class Foo {
    static count = 0;
 
    // This is a static block:
    static {
        if (someCondition()) {
            Foo.count++;
        }
    }
}
```

Think of them as constructor for static properties :smile:.

#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](https://devblogs.microsoft.com/typescript/wp-content/uploads/sites/11/2021/08/inlayHints-4.4-rc-ghd.png "TS inlay hints")

#6. No initializers for Abstract properties
Abstract properties cannot have initializers.
```javascript
abstract class C {
  abstract prop = 1;
  //       ~~~~
  // Property 'prop' cannot have an initializer because it is marked abstract.
}
```

#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](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-4.html).

I run a small YouTube channel named [EverydayJavaScript](https://youtube.com/EverydayJavaScript). Please do subscribe to it if you haven't fallen asleep reading the release notes!

Happy TypeScript-ing!