Technology Blog

Look deep into latest news and innovations happening in the Tech industry with our highly informational blog.

What’s new in TypeScript 4.2?

hkis

Typescript’s 4.2 was just released recently. What awesome features does this release bring? What impact does it have in your daily life as a Developer? Should you immediately update?

Here, we will be going through all the most exciting new features. Here is a summary:

  • Smarter type alias preservation
  • Leading/middle rest elements in tuple types
  • Stricter checks for the in operator
  • –noPropertyAccessFromIndexSignature
  • Template literal expressions have template literal types
  • Improved uncalled function checks in logical expressions
  • Better understanding of the compile process
  • Support for Abstract Constructor Types

To get an editor with the latest Typescript version use Visual Studio Code Insiders. You can use a plugin alternatively for VS Code.

If you just want to have a play while reading the article you can use the Typescript Playground here. It is a fun and super easy tool to use.

Smarter Type Alias Preservation

Sometimes TypeScript just doesn’t resolve types properly. It may return the correct types but just not return the correct alias. The alias could be important and shouldn’t be lost along the way.

Let’s check this function:

export type BasicPrimitive = number | bigint;

export function divisablePer0(value: BasicPrimitive) {
    if (value === 0) {
        return undefined;
    }

    return value;
}

type ReturnAlias = ReturnType<typeof divisablePer0>; // number | bigint | undefined

Notice that an undefined type needs to be added to the method return type as it’s returning undefined on some scenarios.

Before 4.2 the return of type divisablePer0 is number | bigint | undefined. That type is indeed correct but we have lost some information. The alias BasicPrimitive got lost in the process, which is a handy piece of information to have.

If we do the same on TypeScript 4.2 we get the correct alias:

export type BasicPrimitive = number | bigint;

export function divisablePer0(value: BasicPrimitive) {
    if (value === 0) {
        return undefined;
    }

    return value;
}

type ReturnAlias = ReturnType<typeof divisablePer0>; // BasicPrimitive | undefined

Now the method divisablePer0 has the proper return type: BasicPrimitive | undefined. That makes your code more readable just by upgrading.

Leading/middle Rest Elements in Tuple Types

In the article about mapped types here we already looked at TypeScript Tuples. As a refresher, let’s revisit the example:

let arrayOptions: [string, boolean, boolean];
arrayOptions = ['config', true, true]; // works
arrayOptions = [true, 'config', true];
//             ^^^^^  ^^^^^^^^^
// Does not work: incompatible types

function printConfig(data: string) {
  console.log(data);
}

printConfig(arrayOptions[0]);

However, we forgot to check whether Tuples can use optional elements. Let’s see what the previous example would look like:

let arrayOptions: [string, boolean?, boolean?];
arrayOptions = ['config', true, true]; // works
arrayOptions = ['config', true]; // works too
arrayOptions = ['config']; // works too

function printConfig(data: string) {
  console.log(data);
}

printConfig(arrayOptions[0]);

Prior to 4.2 we could even use the spread operator to indicate a dynamic number of elements:

let arrayOptions: [string, ...boolean[]];

arrayOptions = ['config', true, true]; // works
arrayOptions = ['config', true]; // works too
arrayOptions = ['config']; // works too

function printConfig(data: string) {
  console.log(data);
}

printConfig(arrayOptions[0]);

In this new TypeScript, version Tuples become more powerful. Previously, we could use the spread operator but we couldn’t define the last element types.

let arrayOptions: [string, ...boolean[], number];
arrayOptions = ['config', true, true, 12]; // works
arrayOptions = ['config', true, 12]; // works too
arrayOptions = ['config', 12]; // works too

function printConfig(data: string) {
  console.log(data);
}

printConfig(arrayOptions[0]);

Note that something like this is invalid:

let arrayOptions: [string, ...boolean[], number?];

An optional element can’t follow a rest element. However, note that …boolean[] does accept an empty array, so that Tuple would accept [string, number] types.

Let’s see that in detail in the following example:

let arrayOptions: [string, ...boolean[], number];
arrayOptions = ['config', 12]; // works

Stricter Checks for the in Operator

The in operator is handy to know if a method or a property is in an object. However, in JavaScript, it will fail at runtime if it’s checked against a primitive.

Now, when you try to do this:

"method" in 23
//          ^^
// Error: The right-hand side of an 'in' expression must not be a primitive.

You’ll get an error telling you explicitly what’s going on. As this operator has been made stricter this release might introduce breaking changes.

--noPropertyAccessFromIndexSignature

Yet another compiler configuration that’s always interesting. In TypeScript, you can access properties using the bracketed element syntax or the dot syntax like JavaScript. That accessor is possible when the key is a string.

interface Person {

name: string;

}

const p: Person = { name: 'Max };

console.log(p.name) // Max

console.log(p['name']) // Max

There’s a situation that has led to explicit property miss typing:

interface Person {

name: string;

[key: string]: string;

}

const p: Person = { name: 'Max };

console.log(p.namme) // undefined

console.log(p['namme']) // undefined

Note how we are accessing the wrong property namme but because it fits the [key: string] implicit one, TypeScript won’t fail.

Enabling –noPropertyAccessFromIndexSignature will make TypeScript look for the explicit property when using the dotted syntax.

interface Person {
  name: string;
  [key: string]: string;
}
const p: Person = { name: 'Max' };
console.log(p.namme)
//          ^^^^^^^^
// Error
console.log(p['namme']) // works fine

It’s not part of the strict configuration as this might not suit all developers and codebases.

Template Literal Expressions Have Template Literal Types

Template literal types were introduced in 4.1 and here they got smarter. Previously, you couldn’t define a type template usage template literals.

type PropertyType = `get${string}`;

function getProperty(property: PropertyType, target: any) {
    return target[property];
}

getProperty('getName', {}); // works

const propertyName = 'Name';

const x = `get${propertyName}`;

getProperty(x, {});
//         ^^^
// Error: Argument of type 'string' is not assignable to parameter of type '`get${string}`'

The core problem is that string expressions are resolving to type string which leads to this type of incompatibility:

const x = `get${propertyName}`; // string

However, with 4.2, template string expressions will always start out with the template literal type:

const x = `get${propertyName}`; // getName

Improved Uncalled Function Checks in Logical Expressions

TypeScript’s uncalled function checks apply within && and || expressions. Under –strictNullChecks you will check the following error now:

function isInvited(name: string) {
    return name !== 'Robert';
}

function greet(name: string) {
    if (isInvited) {
    //  ^^^^^^^^^
    // Error:
    // This condition will always return true since the function is always defined.
    // Did you mean to call it instead?
        return `Welcome ${name}`;
    }
    return `Sorry you are not invited`;
}

Better Understanding of the Compile Process

Sometimes it can be quite challenging to work out where the Typescript file definitions are pulled from. It’s sometimes a trial and error process.

It’s now possible to get a deeper insight into what’s going on, making the compiler more verbose, using the following:

tsc --explainFiles

Let’s see the result:

Pic courtesy: betterprogramming.pub

It is an awesome feature that will help you understand further Typescript’s internals.

For more information and to develop web application using TypeScript, Hire TypeScript Developer from us as we give you a high-quality product by utilizing all the latest tools and advanced technology. E-mail us any clock at – hello@hkinfosoft.com or Skype us: “hkinfosoft”. To develop custom web apps using TypeScript, please visit our technology page.

Content Source:

  1. blog.logrocket.com