Our Global Presence
Canada
57 Sherway St,
Stoney Creek, ON
L8J 0J3
India
606, Suvas Scala,
S P Ring Road, Nikol,
Ahmedabad 380049
USA
1131 Baycrest Drive,
Wesley Chapel,
FL 33544
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:
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.
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.
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
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 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
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`; }
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:
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:
57 Sherway St,
Stoney Creek, ON
L8J 0J3
606, Suvas Scala,
S P Ring Road, Nikol,
Ahmedabad 380049
1131 Baycrest Drive,
Wesley Chapel,
FL 33544
57 Sherway St,
Stoney Creek, ON
L8J 0J3
606, Suvas Scala,
S P Ring Road, Nikol,
Ahmedabad 380049
1131 Baycrest Drive,
Wesley Chapel,
FL 33544
© 2024 — HK Infosoft. All Rights Reserved.
© 2024 — HK Infosoft. All Rights Reserved.
T&C | Privacy Policy | Sitemap