7 New and Exciting TypeScript Features - Bits and Pieces

January 02, 2020 0 Comments

7 New and Exciting TypeScript Features - Bits and Pieces

 

 

Note: Before diving into any of these features, you should check out the TypeScript playground where you can test out all the features. I would recommend that you switch to an older version (click on the version dropdown at the top left corner) to see how the newer version handles a use-case that was not supported earlier:

TypeScript playground demo

Tip: Use Bit (Github) to build your UI component collection. It’s just like a component library only each component is versioned and installed completely independently. Enjoy faster development and a consistent UI without ever losing focus on your main work. Simply, harvest reusable components from your apps, as you go. It’s that easy.

Bit supports Javascript, TypeScript, React, React TypeScript, Angular and Vue.

bit.dev

1. Optional Chaining

Available in v3.7 onwards

This is a real pain point when you try to access nested data, the more nested the data is, more tedious your code can become.

In the below example, to access address you have to traverse through data.customer.address and it is possible that data or customer is undefined So, it is customary to check if every level of that traversal is defined combining with && operator or other similar tricks as seen in the example.

Now, you can use .? operator to optionally chain data access. This way instead of crashing at runtime, the nested chain will return undefined anywhere in the chain if there is a parent that is not defined yet.

Optional Chaining

2. Nullish Coalescing

Available in v3.7 onwards

The Nullish Coalescing (??) operator is an alternative to the OR (||) operator. It returns the right-side expression if the left-side is null or undefined. How does this differ from || ? || is essentially the boolean OR operator in JavaScript and we try to leverage short circuiting to return the first non-false value. This might have unintended consequences because the number 0 or an empty string would be considered false when that might be a valid input as a requirement. Let’s illustrate that with an example:

Nullish Coalescing

This way we can unambiguously differentiate between something that is undefined or a false value (which can be tricky because of the way JavaScript assumes what is falsified)

3. Recursive Type Aliases

Available in v3.7 onwards

Most of the real world data types are recursive. For example, if you are trying to deal with data that is hierarchic, you find repeating patterns of data of the same type. A good example is JSON, which is essentially a hash map which in turn could contain another map by itself or an array of maps.

Until v3.6, if you had to define a simple JSON type, it will have to be like

[1] interface JSONObject { [x: string]: JSONValue; }[2] interface JSONArray extends Array<JSONValue> { }[3] type JSONValue = string | number | boolean | JSONObject | JSONArray

If you try to overlay the types on lines 1 and 2 inline as a single line on 3, you might get the following error Type alias JSONValue circularly references itself

This has been effectively solved in v3.7 and you can write it simply like below:

type JSONValue = string | number | boolean | { [x: string]: JSONValue } | Array<JSONValue>

4. Assert Signatures

Available in v3.7 onwards

You should know that TypeScript has type guards that play well with native typeof and instanceOf operators in JavaScript. This helps us add prerequisites to function parameters to restrict them to be specific types.

Assuming, we put all that to use, let’s add type guards to make sure given input is a date and extract the year component out of it.

Assert Signatures

The above code looks all nice but TypeScript will still complain that getFullYear is not available on unknown type

Now, starting v3.7, TypeScript has a new keyword called asserts that will let the compiler know the right type from the point of assertion onwards. For the assertion function, instead of the return type add asserts <param> as <type>

That way if the assertion passes, TypeScript will assume the parameter is the defined type going forward. The updated code will look like:

Assert Signature

5. Better feedback for Promises

Improved since 3.6

It is a common mistake to try to use the payload of a promise directly in the code and forgetting to use await or then as illustrated below:

TypeScript will be completely ignorant of the Promise and show an error message not related to it like below:

No hint about the promise

v3.6 onwards the compiler is smart enough to suggest that you should may be resolve the promise. Notice, how the latest compiler treats the same error:


Tag cloud