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());
}
Now
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
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:
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
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:
interface Person {
name: string;
age?: number;
}
The equivalent of the above interface was:
interface Person {
name: string;
age?: number | undefined;
}
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.
};
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++;
}
}
}
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โ.
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.
}
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!
Top comments (5)
That's why I love ๐ Typescript ๐
Example second of can be
catch(err ) {
console.error((err as Error).message);
}
if so, then it's not worth using useUnknownInCatchVariables. Using 'as' this way, you're not guarding the type, only forcing it
yup I hate the as keyword typecasting.
Yeah even this can be used. But to be honest, I hate type castings using 'as' keyword.