What’s new TypeScript 2.4

This is my first blog post on TypeScript open source programming language. I really impressed with the TypeScript benefits after working with Angular framework for quite some time. Of course, it is also very popular in other JS based frameworks such as ExpressJS, ReactJS, VueJS and so on. If you have prior knowledge on Object-Oriented Programming(OOPs) based languages(for example, java) then you feel that TypeScript is really simple with it’s known concepts and terminology. The static type-checking nature introduced compile -time error checks(no more surprise on runtime errors) and great tooling support with IntelliSense to this dynamic type JavaScript world.

“TypeScript is a superset of JavaScript that brings static types and powerful tooling to JavaScript”

TypeScript team announced 2.4 version with four major improvements

  1. Dynamic Import Calls
  2. Weak Types
  3. String Enums
  4. Safter Callback Parameters.

Let’s we dive deep into these features one by one

Dynamic Import Expressions:

This feature allows you to load the modules asynchronously or lazily at any arbitrary point of time in your program. The dynamic import calls or expressions are new features of ECMAScript specification.The new import() calls anticipated especially for ES2018 or later modules(It will not work with lower releases).These calls will import the module and the return a promise to that module.

Let us take an example of a carousel website where you need to view  the available products. Generally most of the users prefer viewing the image gallery. But in few cases it has to provide the functionality to download all the images at once. This uncommon and resource costly scenario need to be handled separately.

The below  zip creation method gives you more insight into this specific scenario 

async function getZipFile(name: string, files: File[]): Promise<File> {
    const zipUtil = await import('./utils/create-zip-file');
    const zipContents = await zipUtil.getContentAsBlob(files);
    return new File(zipContents, name);
}

 The example shows that the modules await-ed in an async function as part of asynchronous operations. You can also apply callbacks using .then constraint. 

import('./utils/create-zip-file')
  .then(content => 
     console.log("The zipped content size is "+content.size()))

At the end, this feature brings  you the following benefits,

  •    In most of the cases, You can pass less JS code over the network.
  •    The page response time will be quick for lower bandwidth networks and critical content 

Weak types

TypeScript introduced optional parameters feature considering the default behavior (omit few parameters in the function call) of JavaScript.  Later it introduced the excessive properties in the object literals too.In other ways, adding a string index signature if you’re sure that the object can have some extra properties.

Let us demonstrate this feature in a better way with an example. The square configuration which holds extra properties as below

interface SquareConfigOptions {
        color?: string;
        width?: number;
        [propName: string]: any;
}

One short coming of this approach is that the defined check fails if you won’t pass the object literal immediately with an appropriate type. That means, it won’t handle unexpected properties. The newer version introduced “WeakTypes” feature where all the properties of an object are optional. If you try to assign any value to a weak type it leads to an error.

Let’s try to calculate the area of square entity,

function findArea(options: Options) {
    // ...
}

const options = {
    radius: 100,
    angle: 60,
}

// Error!
findArea(options);

In the above code snippets, the area method called with an inappropriate arguments. i.e, There is no overlap properties between the options object and squareConfigOptions interface. This leads to a compile time checking and avoids the runtime errors in your project.

This feature is a breaking change for the existing code base. Hence please follow the below workarounds to make it compatible with any kind of version.

  1. Declare the properties if they already exists.
  2. Add index signature for weak types ([propName: string]: any;).
  3. Use Type assertions (options as squareConfigOptions)

String enums

Initially, Typescript introduced enum feature to handle the constant well-known numeric values as a set.For example, the color enum would be written as follows,

enum Color {
    R = 1,
    G = 2,
    B = 3,
}

The main disadvantage of this enum feature is that it will not reveal proper meaning to the context and debugging  is going to be difficult. Apart from that, it supports string literals types which can be used in unions.

function setColor(color: "red" | "green" | "blue")
{ // ... } 
setColor("red");

The above construct makes an easy way of debugging and well serialization over the protocols. To get the advantage of both features it introduced the concept called “String enums”. One pit fall from this approach is that you can’t access values through index based access(i.e, color[“red”]).The newer approach of String enums would be written as follows

enum color {
   RED = "RED",
   GREEN = "GREEN",
   BLUE = "BLUE"
}

Safer callback parameter checking

In TypeScript function parameter bivariance denotes that comparing the functional assignment bidirectionally when you wants to assign two functions each other. This concept won’t be a matter in most of the cases but it will collapse the system when you are going to deal with callbacks. For example, Promises and Observables need a special attention in this case.

Let us take an example of Vehicle and Car relationship. The bidirectional assignment is a common behavior in the OOPs paradigm.The same applies for TypeScript as well.But this is going to be an issue when you are dealing with callback parameters.

interface Vehicle {
  engine : any
};

interface Car extends Vehicle {
  CC() : void ;
  gears(): void
};

interface itemCollection<T> {
  forEach(callback : (value : T) => void) : void;
}

declare let vehicleCollection : itemCollection<Vehicle>;
declare let carCollection : itemCollection<Car>;

// This should be an error, but TypeScript 2.3 and below allow it.
carCollection = vehicleCollection;

Finally you’ll see much better checking when using Promises, Observables, and also when you’ve been using callbacks.

Conclusion:

TypeScript 2.4 release introduced new constraints which enables the static typing more powerful and robust. Hope we can see more features in the next releases.  See you Geeks 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *