TypeScript – ES features

Reading Time: 5 minutes

This blog post gives an overview of the ECMAScript and ECMAScript features.

Before diving into ES features, let us look at what ECMAScript and why do developers need to know about it.

What is ECMAScript?

ECMAScript is a scripting language specification standardized by ECMA International in ECMA-262 and ISO/IEC 16262.

I.e. ECMAScript provides the rules, guidelines, and recommendations that a scripting language must adhere to be compliant with ECMAScript

JavaScript is an implementation of ECMAScript.

Let us look at major features released as part of ES6, ES7, ES8 and ES9.

ES6

  • Default Parameters
  • Template Literals
  • Classes
  • Block scope for let and constants
  • Arrow Functions
  • Improved Object Literals
  • Destructuring
  • REST and SPREAD operators
  • Promises

ES7

  • Array.prototype.inlcudes
  • Exponential operator

ES8

  • Async Functions
  • Object.values and Object.entries
  • String Padding

ES9

  • Asynchronous Iterations

Default Parameters

Default parameters allow you to set the default values for your function parameters. If no value or undefined to the function, the function will take the default value assigned for the parameter.

function add(num1:number,num2:number=10){
   var result = num1 + num2;
   console.log('params received num1 =>' + num1 + ' and num2=> '+num2 +'; result: ' +result);
}
add(1); //params received num1 =>1 and num2=> 10; result: 11
add(1,5); //params received num1 =>1 and num2=> 5; result: 6

Template Literals

Template literals are enclosed by the backtick (“`”) symbol. Template literals can contain placeholders. These are indicated by the dollar sign and curly braces (${expression}). The expressions in the placeholders and the text between the back-ticks (` `) get passed to a function.

Template literals are used for 

  • String Interpolation
  • Multiline strings
  • Tagged templates

String Interpolation

When you want to generate some string out of some static strings and some variables, you can use string interpolation.

let todayDate='08-07-2019';
console.log('Today date is '+ todayDate); // Without String interpolation
//result -> Today date is 08-07-2019
console.log(`Today date is ${todayDate}`); // String interpolation
//result -> Today date is 08-07-2019

Any placeholder inside the interpolation (${ and }) is treated as a JavaScript expression and evaluated. 

Multiline Strings

Template strings allow you to concatenate the multiple lines of strings without the need of adding newline character (‘\n’).

console.log('Multilines strings complex\n' +
'without string literals');
// "Multilines strings complex
// without string literals"

console.log(`Multilines strings complex
without string literals`);
// "Multilines strings complex
// without string literals"

Tagged templates

A more advanced form of template literals are tagged templates. Tags allow you to parse template literals with a function. The first argument of a tag function contains an array of string values. The remaining arguments are related to the expressions. In the end, your function can return your manipulated string (or it can return something completely different as described in the next example). The name of the function used for the tag can be whatever you want. 

var person = 'Williams';
var age = 32;

function myTag(strings, personExp, ageExp) {
 var str0 = strings[0]; // "That "
 var str1 = strings[1]; // " is a "

 // There is technically a string after
 // the final expression (in our example),
 // but it is empty (""), so disregard.
 // var str2 = strings[2];

 var ageStr;
 if (ageExp > 40){
   ageStr = 'oldman';
 } else {
   ageStr = 'youngster';
 }

 // We can even return a string built using a template literal
 return `${str0}${personExp}${str1}${ageStr}`;
}

var output = myTag`That ${ person } is a ${ age }`; //

console.log(output);
// That williams is a youngster

Block scope for let and constants

In Typescript, we can define variables using var, let and const. The difference comes in terms of accessibility of the variable (scope).

Scope essentially means where these variables are available for use. 

The difference between var, let and const will be explained in a different topic as it deserves a separate post

var declarations are globally scoped or function/locally scoped. It is globally scoped when a var variable is declared outside a function. This means that any variable that is declared with var outside a function block is available for use in the whole window. var is function scoped when it is declared within a function. This means that it is available and can be accessed only within that function.

Arrow Functions

Arrow functions (A.K.A Fat Arrow Functions) are used for anonymous functions. These functions are also known as lambda functions in other languages.

Arrows are a function shorthand using the => syntax. 

Syntax:

(param1, param2, ..., paramN) => expression

Example:

let sum = (x: number, y: number): number => { return x + y; } 
sum(10, 20); //returns 30

In the above example, sum is an arrow function. (x:number, y:number) denotes the parameter types, :number specifies the return type. The fat arrow => separates the function parameters and the function body. The right side of => can contain one or more code statements.

Improved Object Literals

Object Literals make it easy to create the objects with properties inside the curly braces. Three major ways of doing it is

  • Shorthand syntax for initializing properties from variables
  • Shorthand syntax for defining function methods
  • Ability to have computed property names in an object literal definition

Shorthand syntax for initializing properties from variables

function getCar(make:string, model:string, year:number) {
       return {
           make,
           model,
           year
       }
   }

var carModel = getCar("Ford","Fortuner",2019);
console.log(carModel);
//result - {make: "Ford", model: "Fortuner", year: 2019}

Shorthand for writing Methods

function getCar(make:string, model:string, year:number) {
       return {
           make,
           model,
           year,
           getModel(){
               return model;
           }
       }
   }

var carModel = getCar("Ford","Fortuner",2019);
console.log(carModel); //result - {make: "Ford", model: "Fortuner", year: 2019}
console.log(carModel.getModel()); // result - Fortuner

Ability to have computed property names in an object literal definition

function getCar(make:string, model:string, year:number) {
       return {
           make,
           model,
           year,
           ['make' + make]: true,
           getModel(){
               return model;
           }
       }
   }

var carModel = getCar("Ford","Fortuner",2019);
console.log(carModel);
//result - {make: "Ford", model: "Fortuner", year: 2019, makeFord: true, getModel: ƒ}
console.log(carModel.getModel()); // result - Fortuner

Destructoring

Destructuring is a way of extracting values into variables from data stored in objects and arrays.

There are three types 

  • Object Destructuring
  • Array Destructuring
  • Function Parameter Destructuring

Object Destructing

We want to extract the make and model of the car object into carMake and CarModel properties. Below is the sample of destructuring.

let car = {make: "Ford", model: "Fortuner", year: 2019, makeFord: true}

const {make: carMake, model:carModel} = car;
console.log({ carMake }); // result -> {carMake: "Ford"}
console.log({ carModel }); // result -> {carModel: "Fortuner"}

Array Destructing

Array destructuring works in a similar way except it extracts based on the index in the array.

const arr = ['Ford', 'Fortuner'];
const [make, model] = arr;
console.log({make}); // result -> {make: "Ford"}
console.log({model}); // result -> {model: "Fortuner"}

Function Parameter Destructuring

if we want to pass multiple params to a function, with maybe some optional parameters, we would pass it in as an object.

function logMessages(options:any) {
 console.log(options.make); //Result -> Ford
 console.log(options.model);//Result -> Fortuner
}
logMessages({make:'Ford', model:'Fortuner'});

Promises

Below is the simple promise

const one = new Promise<string>((resolve, reject) => {});

In this Promise, I have used the promise constructor to take in a string as the generic type for the Promise’s resolve value. The promise constructor takes an executor callback which the compiler will call by the runtime with these two arguments

Resolve: This is a function that is used to resolve the promise

Reject: This is a function that is used to reject the promise.

So, our promise can either be resolved, or rejected. The resolve part is taken care of by “.then”, and the reject part is taken care of by “.catch”.

one.then(value => {
  console.log('resolved', value);
});
one.catch(error => {
  console.log('rejected', error);
});

The then function actually creates a new Promise that is distinct from the Promise that the then function belongs to. 

If we resolve a Promise, then callbacks are executed. Else, it means that the Promise is rejected and the catch callbacks are executed.

Promise resolutions are easy to write:

resolve('Hello');

Promise rejections, on the other hand, should only be done in exceptional cases. It is considered as a bad practice to reject a promise with a raw string. Always use the error constructor new Error when rejecting a promise.

reject(new Error('failed'));
0 0 vote
Article Rating