TypeScript enums

This blog is a part of my TypeScript series, and the previous ones are:

1. Why program in TypeScript
2. Structural vs nominal typing
3. Getting started with TypeScript classes
4. Access modifiers public, private, and protected
5. Abstract classes

Enumerations (a.k.a. enums) allow you to create limited sets of named constants that have something in common. For example, a week has seven days, and you can assign numbers from 1 to 7 to represent them. But what’s the first day of the week?

According to the standard ISO 8601, Monday is the first day of the week, which doesn’t stop such countries as USA, Canada, and Australia consider Sunday as the first day of the week. Hence using just numbers from 1 to 7 for representing days may not be a good idea. Also, what if someone will assign the number 8 to the variable that store the day? We don’t want this to happen and using day names instead of the numbers makes our code more readable.

On the other hand, using numbers for storing days is more efficient than their names. So we want to have readability, the ability to restrict values to a limited set, and efficiency in storing data. This is where enums can help.

TypeScript has the enum keyword that can define a limited set of constants, and we can declare the new type for weekdays as follows:

enum Weekdays {
  Monday = 1,
  Tuesday = 2,
  Wednesday = 3,
  Thursday = 4,
  Friday = 5,
  Saturday = 6,
  Sunday = 7
}

Here, we define a new type Weekdays that has a limited number of values. We initialized each enum member with a numeric value, and a day of the week can be referred using the dot notation:

let dayOff = Weekdays.Tuesday;

The value of the variable dayOff is 2, but if you’d be typing the above line in your IDE or in TypeScript Playground, you’d be prompted with the possible values as shown on the next screenshot.

Using the members of the enum Weekdays stops you from making a mistake and assigning a wrong value (e.g. 8) to the variable dayOff. Well, strictly speaking, nothing stops you from ignoring this enum and write dayOff = 8 but this would be a misdemeanor.

We could initialize only Monday with 1, and the rest of the days values will be assigned using auto-increment, e.g. Tuesday will be initialized with 2, Wednesday with 3 and so on.

enum Weekdays {
  Monday = 1,
  Tuesday,
  Wednesday,
  Thursday,
  Friday,
  Saturday,
  Sunday
}

By default, enums are zero-based, and if we wouldn’t initialize the Monday member with one, its value would be zero.

Reversing numeric enums

If you know the value of the numeric enum, you can find the name of the corresponding enum member. For example, you may have a function that returns the weekday number and you’d like to print its name. By using this value as an index, you can retrieve the name of the day.

enum Weekdays {  // Declaring a numeric enum
  Monday = 1,
  Tuesday,
  Wednesday,
  Thursday,
  Friday,
  Saturday,
  Sunday
}

const getDay = () => 3;  // A function that returns 3
const today = getDay();  // today is equal 3

console.log(Weekdays[today]);  // Getting the name on the member that’s equal to 3 

In the last line, we retrieve the name of the day, and it’ll print Wednesday on the console.

In some cases, you don’t even care which numeric values are assigned to the enum members, and the following function convertTemperature() illustrates this. It converts the temperature from Fahrenheit to Celsius or visa versa. In this version of convertTemperature(), we won’t use enums, but then will re-write it with them. This function takes two parameters: temperature and conversion direction

function convertTemperature(temp: number, fromTo: string): number { 

  return ('FtoC' === fromTo) ?
      (temp - 32) * 5.0/9.0:  // Convert from Fahrenheit to Celsius
      temp * 9.0 / 5.0 + 32;  //Convert from Celsius to Fahrenheit
}

console.log(`70F is ${convertTemperature(70, 'FtoC')}C`);  
console.log(`21C is ${convertTemperature(21, 'CtoF')}F`);  
console.log(`35C is ${convertTemperature(35, 'ABCD')}F`);  

This function converts the value from Celsius to Fahrenheit if you pass any value as a fromTo parameter except FtoC. In the last line, we purposely provided the erroneous value ABCD as a fromTo parameter, and this function still converts the temperature from Celsius to Fahrenheit. The attempts to invoke a function with the erroneous values should be caught by the compiler and this is what TypeScript enums are for. You can see it in action here.

In the next listing, we declare the enum Direction that restricts the allowed constants to either FtoC or CtoF and nothing else. We also changed the type of the fromTo parameter from a string to Direction.

enum Direction {  // Declaring the enum Direction 
  FtoC,
  CtoF
}

function convertTemperature(temp: number, fromTo: Direction): number {  

      return (Direction.FtoC === fromTo) ?
             (temp - 32) * 5.0/9.0:
             temp * 9.0 / 5.0 + 32;
}

console.log(`70F is ${convertTemperature(70, Direction.FtoC)}C`); 
console.log(`21C is ${convertTemperature(21, Direction.CtoF)}F`); 

Since the type of the second parameter of the function is Direction, we have to invoke this function providing one of this enum’s member, e.g. Direction.CtoF. We’re not interested in what is the numeric value of this member. The purpose of this enum is just to provide a limited set of constants: CtoF and FtoC. The IDE will prompt you with two possible values for the second parameter, and you won’t make a mistake providing a random value.

Enum members are initialized with values (either explicitly or implicitly). All examples included in this section had enum members initialized with numbers, but TypeScript allows you to create enums with string values, and we’ll see such examples next.

String enums

In some cases, you may want to declare a limited set of string constants, and you can use string enums for this, i.e. enums that have their members initialized with string values. Say you’re programming a computer game where the player can move in the following directions:

enum Direction {
    Up = "UP",       
    Down = "DOWN",   
    Left = "LEFT",   
    Right = "RIGHT", 
}

When you declare a string enum, you must initialize each member. You may ask, “Why not just use a numeric enum here so TypeScript would automatically initialize its members with any numbers?” The reason is that in some cases you want to give meaningful values to the enum members. For example, you need to debug the program and instead of seeing that the last move was 0, you’ll see that the last move was UP.

And the next question you may ask, “Why declare the enum Direction if I can just declare four string constants with the values UP, DOWN, LEFT, and RIGHT?” You can, but let’s say we have a function with the following signature:

move(where: string)

A developer can make a mistake (or a typo) and invoke this function as move(“North”). But North is not a valid direction, and it’s safer to declare this function using the enum Direction:

move(where: Direction)

As you see, wrong argument value is caught by the compiler (1), and auto-complete (2) prevents mistakes

We made a mistake and provided a string “North” in line 15, and the compile-time error would read “Argument of type ‘”North”‘ is not assignable to the parameter of type ‘Direction’.” In line 20, the IDE offers you a selection of valid enum members so there’s no way you provide the wrong argument.

Now, let’s imagine that you need to keep track of the app state changes. The user can initiate a limited number of actions in each of the views of your app. Say, you want to log the actions taken in the view Products. Initially, the app tries to load products, and this action can either succeed or fail. The user can also search for products. To represent the states of the view Products you may declare a string enum as follows:

enum ProductsActionTypes {
  Search = 'Products Search', 
  Load = 'Products Load All', 
  LoadFailure = 'Products Load All Failure', 
  LoadSuccess = 'Products Load All Success' 
}

// If the function that loads products fails...
console.log(ProductsActionTypes.LoadFailure);  

When the user clicks on the button to load products, you can log the value of the member ProductsActionTypes.Load, which will log the text ‘Products Load All’. If the products were loaded successfully, log the value of ProductsActionTypes.LoadFailure, which will log the text ‘Products Load All Failure’.

Note: Some state management frameworks (e.g. Redux) require the app to emit actions when the app state changes. If we’d declare a string enum like in the above listing, we’d be emitting actions ProductsActionTypes.Load, ProductsActionTypes.LoadSuccess et al.

Note: String enums are not reversible, and you can’t find the member’s name if you know its value.

const enums

If you use the keyword const while declaring enum, its values will be inlined and no JavaScript will be generated. Let’s compare the generated JavaScript of enum vs const enum. The left side of the following screenshot shows the enum declared without the const, and the right side shows the generated JavaScript. For illustration purposes, in the last line, we just print the next move.

Now let’s just add the keyword const on the first line before the enum, and compare the generated JavaScript (on the right) with the one from the screenshot above.

As you see, the JavaScript code for the enum Direction was not generated – it was erased. But the values of the enum member that was actually used in the code (i.e. Direction.Down) was inlined in JavaScript.

Using const with enum results in more concise JavaScript, but keep in mind that since there is no JavaScript code that would represent your enum, you may run into some limitations, e.g. you won’t be able to reverse the numeric enum member name by its value.

Overall, with enums, the readability of your programs increases. Besides, using enum is the step in the right direction: moving away from the type any.

If you like this blog series, consider reading our book “TypeScript Quickly”. So far, only 175 pages are available, but the publisher will be releasing the new content monthly.
An extra bonus: this book will not only introduce you to TypeScript programming, but you’ll also learn how the blockchain technology works while going over multiple sample apps.

TypeScript access modifiers public, private, protected

This blog is a part of my TypeScript series, and the previous ones are:

1. Why program in TypeScript
2. Structural vs nominal typing
3. Getting started with TypeScript classes

TypeScript includes the keywords public, protected, and private to control access to the members of a class i.e. properties or methods.

Class members marked public can be accessed from the internal class methods as well as from the external scripts. This is a default access.

Class members marked as protected can be accessed either from the internal class methods or from its descendants.

The private class members can be accessed from within the class only.

NOTE: If you know languages like Java or C#, you may already know the concept of restricting the access level with private and protected keywords. But TypeScript is a superset of JavaScript, which doesn’t support the private keyword, so the keywords private and protected (as well as public) are removed during the code compilation. The resulting JavaScript won’t include these keywords and you can consider them just as a convenience during development.

The next screenshot illustrates the protected and private access level modifiers. In line 15, the code can access the protected ancestor’s method sayHello(), because its done from the descendant. But when we clicked Ctrl-Space after this. In line 21, the variable age is not shown in the auto–complete list because it’s declared as private and can be accessed only within the class Person.

This code sample shows that the subclass can’t access the private member of the superclass. In general, only a method from the class Person can access private members from this class.

To try this code on your own, visit the TypeScript playground here.

While protected class members are accessible from the descendant’s code, they are not accessible on the class instance. For example, the following code won’t compile and will give you the error “Property ‘sayHello’ is protected and only accessible within class ‘Person’ and its subclasses”:

const empl = new Employee(); +
empl.sayHello(); // error

DISCLAMER: IMO, the protected access level is useless in any programming language. I explained why they are useless in Java back in 2006. Then I continued my witch hunt against seemengly protected creatures in the Adobe Flex framework. As I’m getting older, my motivation to fight protected variables is not as strong as it used to be. Live and let live.

Let’s look at another example of the class Person, which has a constructor, two public and one private property. First, we’ll write a long version of the class declaration.

class Person {
    public firstName: string;
    public lastName: string;
    private age: number;

    constructor(firstName:string, lastName: string, age: number) {
        this.firstName = firstName;
        this.lastName;
        this.age = age;
    }
}

The constructor in the class Person performs a tedious job of assigning the values from its argument to the respective members of this class. By using access qualifiers with the constructor’s arguments, you instruct the TypeScript compiler to create class properties having the same names as constructor’s arguments. The compiler will auto-generate the JavaScript code to assign the values given to the constructor to class properties. This will make the code of the TypeScript class more concise as shown in the next screenshot.

TIP: If you’d use just the readonly qualifier with constructor arguments, TypeScript compiler would also create read-only class variables for them.

In line 8, I create an instance of the class Person passing the initial property values to its constructor, which will assign these values to the respective object’s properties. In line 10, I wanted to print the values of the object’s properties firstName and age, but the latter is marked with a red squiggly line. If you hover the mouse over the erroneous fragment, you’ll see that the TypeScript’s static analyzer (it runs even before the compiler) properly reports an error:

Property age is private and only accessible within class Person.

In the TypeScript playground, the JavaScript code is generated anyway because from the JavaScript perspective, the code in line 10 is perfectly fine. But in your projects, you should always use the compiler’s option noEmitOnError to prevent the generation of JavaScript until all TypeScript syntax errors are fixed.

Implementing a singleton with a private constructor

Imagine, you need to create a single place that serves as a storage of important data in memory representing the current state of the app. Various scripts can have an access to this storage but you want to make sure that only one such object can be created for the entire app, also known as a single source of truth.

Singleton is a popular design pattern that restricts the instantiation of a class to only one object. How do you create a class that you can instantiate only once? It’s a rather trivial task in any object-oriented language that supports the private access qualifier.

Basically, you need to write a class that won’t allow using the new keyword, because with the new, you can create as many instances as you want. The idea is simple – if a class has a private constructor, the operator new will fail.

Then, how to create even a single instance of the class? The thing is that if the class constructor is private, you can access if only within the class, and as the author of this class, you’ll responsibly create it only once by invoking that same new operator from the class method.

But can you invoke a method on a class that was not instantiated? Of course, you can! JavaScript (as well as its big brother TypeScript) support static class members, which are shared between multiple instances of the class.

The next listing shows our implementation of the singleton design pattern in a class AppState, which has the property counter. Let’s assume that the counter represents our app state, which may be updated from multiple scripts in the app.

Any of such scripts must update the only place that stores the value of the counter, which is the singleton instance of AppState. Any script that needs to know the latest value of the counter will also get it from the AppState instance.

The class AppState has a private constructor, which means that no other script can instantiate it using the statement new. It’s perfectly fine to invoke such a constructor from within the AppState class, and we do this in the static method getInstance().

The method getInstance() is static, and this is the only way we can invoke a method in the absence of the class instance.

class AppState {

    counter = 0;  
    private static instanceRef: AppState;

    private constructor() { }

    static getInstance(): AppState {
        if (AppState.instanceRef === undefined) {
            AppState.instanceRef = new AppState();
        } 

        return AppState.instanceRef; 
    }
}

// const appState = new AppState(); // error because of the private constructor

const appState1 = AppState.getInstance(); 

const appState2 = AppState.getInstance();

appState1.counter++;
appState1.counter++;
appState2.counter++;
appState2.counter++;

console.log(appState1.counter); // prints 4 
console.log(appState2.counter); // prints 4

Both console.log() invocations will print 4 as there is only one instance of AppState.

To see this code sample in CodePen, visit this page.

Starting a new book on TypeScript

It’s Saturday morning and it’s raining in New York City. There is not much you can do. Why not start writing a new book? The agreement with the publisher is signed, and my colleague Anton Moiseev kindly agreed to be my co-author again. The book will have a title TypeScript Quickly, and its first chapters have to be released in October 2018.

In this blog, I’ll show you the first two pages that I just wrote as well as a table of contents (subject to change). Besides introducing the code samples illustrating the syntax of the language, we’ll be developing a blockchain app using TypeScript in different environments: in Node.js, in the browser without frameworks, with Angular, with React… Meanwhile, the first two pages are ready.

Unit 1. Getting started with TypeScript

This unit starts by presenting the benefits of programming in TypeScript over JavaScript. Then we’ll install the TypeScript compiler and the IDE, and you’ll learn about the process of transforming a TypeScript program into its JavaScript equivalent that can be run in any JavaScript engine. After that, you’ll see how various TypeScript types can be used in a program. In the hands-on section, we’ll introduce you to the blockchain project and will develop a library that will be used in subsequent units.

We’d like to make a clear distinction between the syntax introduced in ECMAScript specification, and the syntax that’s unique to TypeScript. That’s why we recommend you to read the Appendix A first, so you know where ECMAScript ends and TypeScript begins.

Why program in TypeScript

TypeScript is a compile-to-JavaScript language. It’s also a superset JavaScript, which means that you can take any JavaScript file, e.g. myProgram.js, change its name extension from .js to .ts, and the file myProgram.ts becomes a valid TypeScript program without changing a single line of code.

The word superset means that it contains something additional compared to the set. The main addition to the JavaScript is static types. You can declare a variable of a certain type, and any attempt to assign a value of a different type to it results in a compilation error. This is not the case in JavaScript, where you can change the type of a variable anytime you want during runtime.

But web browsers don’t support TypeScript and this won’t change in the foreseeable future. The program written in TypeScript has to be transpiled into JavaScript first, and then it can be executed in the browser or a standalone JavaScript engine.

The difference between transpiling and compiling is that the latter turns the source code of a program into a bytecode or machine code, whereas the former converts the program from one language to another, e.g. from TypeScript to JavaScript.

Then why go through a hassle of writing a program in TypeScript and then transpiling it into JavaScript, if you could write this program in JavaScript in the first place?

In essence, TypeScript is JavaScript with static types. For example, if you declare a variable as a string, trying to assign a numeric value to it will result in the compile-time error.

let customerId: string
customerId = 123;  // compile-time error

In JavaSript, you can’t explicitly assign the type to a variable, and you could write

let customerId = "A15BN";
customerId = 123;  // no errors 

Let’s write a JavaScript function that applies the provided discount to a price. It has two arguments and both must be numbers.

function getFinalPrice(price, discount) {
  return price - price/discount;
}

How do you know that the arguments must be numbers? First of all, you wrote this function and having an exceptional memory, you may just remember all types of all functions arguments. Secondly, you use descriptive names of the arguments that hint their types. Thirdly, you could guess the types by reading the function code.

This is a pretty simple function, which is not always the case. But let’s say someone (not you) would invoke this function by providing a discount as a string, this function would print NaN during the runtime.

console.log(getFinalPrice( 100, 10));    // prints 90
console.log(getFinalPrice( 100, "10%")); // prints NaN

In TypeScript, you could provide the types for the function arguments, so if someone would try to invoke the function with a wrong type of an argument, this error would be caught as you were typing. Let’s see it in action.

The official TypeScript web page is located here. It offers the language documentation and a playground, where you could enter the code snippets in TypeScript, which would be immediately transpiled into JavaScript.

Follow this link https://bit.ly/2IyVNlj, and you’ll see our code snippet in the TypeScript playground, with the squiggly red line under “10%”. If you hover the mouse over the erroneous code, you’ll see a prompt explaining the error as shown below.

This error was caught by the TypeScript static code analyzer as I was typing. Moreover, if you specify the variable types, your IDE would offer the auto-complete feature suggesting you the argument names and types of the getFinalPrice() function.

Isn’t it nice that the errors are caught during the compile time? I think so. The vast majority of the developers with the background in such languages as Java, C++, C# and others take it for granted that the errors are caught during compile time, and they welcome TypeScript.

Having said that, I need to admit that some of the hard-core JavaScript developers say that TypeScript slows them down by requiring to use types, and in JavaScript, they’d be more productive. But the majority of the web developers are not JavaScript ninjas and can appreciate a helping hand offered by TypeScript.

This is all I got so far.

Below is the current version of the Table of Contents.

Unit 1: Getting started with TypeScript
1.1 Why developing in TypeScript
1.2 Installing and using the TypeScript compiler
1.3 Introducing the Visual Studio Code IDE
1.4 Getting familiar with TypeScript syntax
1.4.1 Type annotations and inferred types
1.5. Hands-on: Starting the blockchain project
1.5.1 Introducing the blockchain project
1.5.2 Developing a library that implements a mining algorithm

Unit 2 Classes and interfaces
2.1 Classes
2.1.1 Instance and static methods
2.1.2 Properties and access modifiers public, private, protected
2.1.3 Constructors
2.1.4 Abstract classes
2.2 Interfaces
2.2.1 Declaring custom types with interfaces
2.2.2 Interface as a contract
2.2.3 Declaring types with classes vs interfaces
2.3 Hands-on: Developing a browser-based blockchain node with TypeScript
2.3.1 Working with DOM elements
2.3.2 Making AJAX requests
2.3.3 Implementing the blockchain node for

Unit 3 Generics
3.1 Intro to Generics
3.2 Creating custom generics
3.3 Hands-on: Developing Angular client for the browser-based blockchain node
3.3.1 Brief overview of Angular
3.3.2 Creating a new app with Angular CLI
3.3.3 Generating Angular components and services
3.3.4 Implementing the blockchain node in Angular

Unit 4 Tooling
4.1 Improving code quality with TSLint
4.2 Bundling the TypeScript code with Webpack
4.4 Debugging TypeScript in the browser
4.5 Unit testing TypeScript code
4.7 Hands-on: Developing React client for the browser-based blockchain node
4.7.1 Brief overview of React
4.7.2 Transpiling TypeScript with Babel
4.7.3 Creating a React app for the blockchain node

Unit 5 Advanced types
5.1 Unions, intersections, and the type keyword
5.2 Enums
5.3 Mapped types
5.4 Conditional types
5.5. Hands-on: Developing a server for discovering blockchain nodes in the network

Unit 6 Advanced TypeScript features
6.1 Decorators
6.1.1 Creating custom decorators
6.2 Mixins
6.3 Dynamic imports
6.4 Hands-on: Implementing peer-to-peer blockchain nodes communication
6.4.1 Introducing WebRTC
6.4.2 Implementing nodes communication via WebRTC

Appendix A Modern JavaScript
A.1 The keywords let and const
A.2 Functions
A.2.1 Default and optional function parameters
A.2.2 Fat arrow function expressions
A.3 Classes and inheritance
A.4. Asynchronous programming
A.4.1 From callbacks to promises
A.4.2 async and await
A.5 Destructuring
A.6 The Spread operator
A.6.1 Cloning objects with the Spread operator
A.7 The Rest operator
A.8 Iterating data collections

Appendix B Using TypeScript with JavaScript libraries
B.1 Type declaration files
B.1.1 How to create type declaration files
B.2 Using the JavaScript lodash library in TypeScript code

RxJS Essentials: Part 9: Dealing with breaking changes in RxJS 6

This article is a part of my RxJS series, and the previous post is here.

My plan for this morning was to spend 15 min skimming through my RxJS slides and code samples for the upcoming presentation. I did this presentation multiple times, and my code samples published on CodePen just worked. No more.

RxJS 6 was recently released, and my code samples stopped working. I’m not sure if these particular issues were listed somewhere as breaking changes, but I’d like to share my findings with you. I’ve been using the following CDN to get RxJS 6: https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.0.0/rxjs.umd.js.

In the past, you could use the Rx object as in Rx.Observable. No more.

rxjs is the new Rx

For example, my code sample that had Rx.Observable.create() is broken in RxJS 6 complaining that Rx is not defined. The broken code is here.

Say you need to get a hold of the Observable object in RxJS 6. I did it using the JavaScript destructuring syntax:

const { Observable } = rxjs;

Now you can just write Observable.create(). This fixed my broken code sample for Observable.create(), and the working version is here.

The next broken code sample was related to operators. I remember reading that dot-chainable operators shouldn’t be used in RxJS 6. Using pipeable operators is the way to go.

For backward compatibility of your app, you need to add the package rxjs-compat to be able to use dot-chainable operators. After replacing all dot-chainable with pipeable operators, uninstall rxjs-compat.

Here’s the broken code sample that uses dot-chainable operators map and filter.

To fix this code, I used the destructuring syntax again to get the pipeable version of the map and filter operators like this:

const { filter, map } = rxjs.operators;

Basically, I replaced this:

Rx.Observable.from(beers)  
    .filter(beer => beer.price < 8) 
    .map(beer => beer.name + ": $" + beer.price) 
    .subscribe()

with this:

const { from } = rxjs; 
const { filter, map } = rxjs.operators;

from(beers).pipe(
    filter(beer => beer.price < 8), 
    map(beer => beer.name + ": $" + beer.price) 
    )
    .subscribe()

The working version of the code sample that uses pipeable operators map and filter is here.

Disclaimer. These were quick fixes that I came up with. I wouldn’t be surprised if there was a different way to accomplished the same results. If you find one, please let me know. Gotta share, right?

And one more thing. Importing observables like this is not cool anymore:

import {Observable} from "rxjs/observable";

You need to do it like this:

import {Observable} from "rxjs";

For detailed coverage of how to migrate RxJS-related code see this doc.

RxJS Essentials: Part 8: Pipeable operators

In this article, we’ll discuss pipeable operators introduced in RxJS 5.5. The previous articles in this series include:

1. Basic Terms
2. Operators map, filter, and reduce
3. Using Observable.create()
4. Using RxJS Subject
5. The flatMap operator
6. The switchMap operator
7. Handling errors with the catch operator

Pipeable operators are those that can be chained using the pipe() function, whereas dot-chaining operators are chained with the dot as shown in this blog. Let’s discuss the dot-chaining operators first to understand why the pipeable operators were introduced in RxJS.

If you have RxJS installed, the dot-chaining operators can be imported from the directory rxjs/add/operator, for example:

import 'rxjs/add/operator/map';
import 'rxjs/add/operator/filter';

These operators patch the code of the Observable.prototype and become a part of this object. If later on, you decide to remove say filter operator from the code that handles the observable stream but will forget to remove the corresponding import statement, the code that implements filter remains a part of the Observable.prototype. When the bundlers will try to eliminate the unused code (a.k.a. tree shaking), they may decide to keep the code of the filter operator in the Observable even though it’s not being used in the app.

RxJS 5.5 introduced pipeable operators that are pure functions and do not patch the Observable. You can import operators using the ES6 import syntax (e.g. import {map} from ‘rxjs/operators’) and then wrap them into a function pipe() that takes a variable number of parameters, i.e. chainable operators.

The subscriber in the next code snippet will receive the same data as the ones from the first code sample in this blog, but it’s a better version from the tree-shaking perspective because it uses pipeable operators. The next code sample includes the import statement assuming that RxJS is locally installed.

import {map, filter} from 'rxjs/operators'; // 1
...
Rx.Observable.from(beers)
    .pipe(  // 2
         filter(beer => beer.price < 8) ,
         map(beer => ${beer.name}: $${beer.price})
      ) 
    .subscribe( 
        beer => console.log(beer),
        err => console.error(err),
        () => console.log("Streaming is over")
);

1.Importing pipeable operators from rxjs/operators instead of rxjs/add/operator
2. Wrapping pipeable operators into the function pipe()

Now if you’ll remove the line filter from the above code snippet, the tree-shaking module of the bundlers (e.g. Webpack 4) can recognize that the imported function is not used and the code of the filter operator won’t be included in the bundles.

To see it in action in CodePen, follow this link.

NOTE: Since the pipeable operators are standalone functions, to avoid conflicts with the JavaScript catch statement the pipeable version of the catch operator is called catchError.

Debugging observables

The operator do and its pipeable equivalent tap performs a side effect (e.g. log some data) for every value emitted by the source observable, but returns an observable that is identical to the source. In particular, these operators can be used for debugging purposes.

Say, you have a chain of operators and want to see the observable values before and after a certain operator is applied. The tap operator will allow you to log the values:

import { map, tap } from 'rxjs/operators';

myObservable$
  .pipe(
    tap(beer => console.log(`Before: ${beer}`)),
    map(beer => `${beer.name}, ${beer.country}`),
    tap(beer => console.log(`After: ${beer}`))
  )
  .subscribe(...);

In this example, we print the emitted value before and after the map operator is applied. The tap operator doesn’t change the observable data – it just passes it through to the next operator or the method subscribe().

Refactor your code to use exclusively pipeable operators, because starting from RxJS 6, the dot-chaining operators will be supported only if you install a compatibility package.

RxJS Essentials. Part 7: Handling errors with the catch operator

In this article, I’ll show you aone of the RxJS operators for error handling – the catch() operator. The previous articles in this series include:

1. Basic Terms
2. Operators map, filter, and reduce
3. Using Observable.create()
4. Using RxJS Subject
5. The flatMap operator
6. The switchMap operator

The Reactive Manifesto declares that a reactive app should be resilient, which means that the app should implement the procedure to keep it alive in case of a failure. An observable can emit an error by invoking the error() function on the observer, but when the error() method is invoked, the stream completes.

A subscription to an observable ends if one of the following occurs:

1. The consumer explicitly unsubscribes
2. The observable invokes the complete() method on the observer
3. The observable invokes the error() method on the observer

RxJS offers several operators to intercept and handle the error before it reaches the code in the error() method on the observer.

* catch(error) – intercepts the error and you can implement some business logic to handle it
* retry(n) – retries the erroneous operation up to n times

* retryWhen(fn) – retries the erroneous operation as per the provided function

In this article, I’ll show you an example of using the catch() operator. Inside the catch() operator you can check the error status and react accordingly. The following code snippet shows how to intercept an error, and if the error status is 500, switch to a different data producer to get the cached data. If the received error status is not 500, this code will return an empty observable and the stream of data will complete. In any case, the method error() on the observer won’t be invoked.

.catch(err => {  
    console.error("Got " + err.status + ": " + err.description);

    if (err.status === 500){
        console.error(">>> Retrieving cached data");

        return getCachedData();  // failover
    } else{
      return Rx.Observable.empty();  // don't handle the error
    }
})

The following listing shows the complete example, where we subscribe to the stream of beers from a primary source – getData() – which randomly generates an error with the status 500. The catch() operator intercepts this error and switches to an alternative source – getCachedData().

function getData(){
    var beers = [
        {name: "Sam Adams", country: "USA", price: 8.50},
        {name: "Bud Light", country: "USA", price: 6.50},
        {name: "Brooklyn Lager", country: "USA", price: 8.00},
        {name: "Sapporo", country: "Japan", price: 7.50}
    ];

    return Rx.Observable.create( observer => {
        let counter = 0;
        beers.forEach( beer => {
                observer.next(beer);   // 1
                counter++;

                if (counter > Math.random()*5) {   // 2
                    observer.error({
                            status: 500,
                            description: "Beer stream error" 
                        });
                } 
            }
        );

        observer.complete();}
    );
}

// Subscribing to data from the primary source
getData() 
    .catch(err => {  // 3
        console.error("Got " + err.status + ": " + err.description);
        if (err.status === 500){
            console.error(">>> Retrieving cached data");
            return getCachedData();   // 4
        } else{
          return Rx.Observable.empty();  // 5  
        }
    })
    .map(beer => beer.name + ", " + beer.country)
    .subscribe(
        beer => console.log("Subscriber got " + beer),
        err => console.error(err),
        () => console.log("The stream is over")
    );

function getCachedData(){  // 6
    var beers = [
        {name: "Leffe Blonde", country: "Belgium", price: 9.50},
        {name: "Miller Lite", country: "USA", price: 8.50},
        {name: "Corona", country: "Mexico", price: 8.00},
        {name: "Asahi", country: "Japan", price: 7.50}
    ];

    return Rx.Observable.create( observer => {
        beers.forEach( beer => {
                observer.next(beer);
            }
        );

        observer.complete();}
    );
}

1. Emit the next beer from the primary data source
2. Randomly generate the error with the status 500
3. Intercept the error before it reaches the observer
4. Failover to the alternative data source
5. Don’t handle the non-500 errors; return an empty observable to complete the stream
6. The alternative data source for failover

The output of this program can look as follows:

Subscriber got Sam Adams, USA
Subscriber got Bud Light, USA
Got 500: Beer stream error
>>> Retrieving cached data
Subscriber got Leffe Blonde, Belgium
Subscriber got Miller Lite, USA
Subscriber got Corona, Mexico
Subscriber got Asahi, Japan
The stream is over

NOTE: To see it in CodePen, follow this link.

Update: With pipeable operators, use catchError instead of catch.

In the next article of this series, I’ll introduce you to the pipeable operators.

If you have an account at O’Reilly’s safaribooksonline.com, you can watch my video course “RxJS Essentials” there.

RxJS Essentials. Part 6: The switchMap operator

In this article I’ll introduce the switchMap() operator. The previous articles in this series include:

1. Basic Terms
2. Operators map, filter, and reduce
3. Using Observable.create()
4. Using RxJS Subject
5. The flatMap operator

In the previous article of this series, I demoed the use of flatMap(). While flatMap() unwraps and merges all the values emitted by the outer observable, the switchMap() operator handles the values from the outer observable but cancels the inner subscription being processed if the outer observable emits a new value. The switchMap() operator is easier to explain with the help of its marble diagram shown next.

The outer observable emits the red circle, and switchMap() emits the item from the inner observable (red diamond and square) into the output stream. The red circle was processed without any interruptions because the green circle was emitted after the inner observable finished processing.

The situation is different with the green circle. The switchMap() managed to unwrap and emit the green diamond, but the blue circle arrived before the green square was processed. So the subscription to the green inner observable was cancelled, and the green square was never emitted into the output stream. In other words, the switchMap() operator switched from processing of the green inner observable to the blue one.

The following example has two observables. The outer observable uses the function interval() and emits a sequential number every second. With the help of the take() operator, we limit the emission to two values: 0 and 1. Each of these values is given to the switchMap() operator, and the inner observable emits three numbers with the interval of 400 milliseconds.

let outer$ = Rx.Observable
               .interval(1000)
               .take(2);

let combined$ = outer$.switchMap((x) => {  
     return Rx.Observable
	          .interval(400)
	          .take(3)
	          .map(y => `outer ${x}: inner ${y}`)
});

combined$.subscribe(result => console.log(`${result}`));

The output of this script is shown next:

outer 0: inner 0
outer 0: inner 1
outer 1: inner 0
outer 1: inner 1
outer 1: inner 2

Note that the first inner observable didn’t emit its third value 2. Here’s the timeline:

1. The outer observable emits zero and the inner emits zero 400 milliseconds later
2. In 800 milliseconds later, the inner observable emits 1
3. In 1000 milliseconds the outer observable emits 1, and inner observable was unsubscribed
4. The three inner emissions for the second outer value went uninterrupted because it didn’t emit any new values

If you replace switchMap() with flatMap(), the inner observable will emit three values for each outer value as shown below.

outer 0: inner 0
outer 0: inner 1
outer 0: inner 2
outer 1: inner 0
outer 1: inner 1
outer 1: inner 2

NOTE: To see it in CodePen, follow this link.

The chances are slim that you’ll be writing outer and inner observables emitting integers but there are various practical use cases for switchMap(). For example, in my Angular apps (Angular comes with RxJS) I use switchMap() with the HttpClient object (it returns observable) to discard the results of the unwanted HTTP requests. Just think of a user that types in an HTML input field (the outer observable) and the HTTP requests are being made (inner observable) on each keyup event. The circles on the diagram are the three characters that the user is typing. The inner observables are HTTP requests issued for each character. If the user entered the third character but the HTTP request for the second one is still pending, the inner observable for the second character gets cancelled and discarded so the browser will never recieve the HTTP response.

TIP. The function interval() is handy if you want to invoke another function periodically based on the specified time interval. For example, myObservable.interval(1000).subscribe(n => doSometing()) will result in calling the function doSomething() every second.

NOTE: If your code has nested subscribe() calls, this should be a red flag to you. Consider re-writing this code using flatMap(), switchMap(), or concatMap().

If you have an account at O’Reilly’s safaribooksonline.com, you can watch my video course “RxJS Essentials” there.

In the next article, I’ll show how to intercept errors from an observable stream with the catch(operator.)

RxJS Essentials. Part 5: The flatMap operator

In this article I’ll introduce an RxJS flatMap() operator. Previous articles in this series include:

1. Basic Terms
2. Operators map, filter, and reduce
3. Using Observable.create()
4. Using RxJS Subject

In some cases, you need to treat each item emitted by an observable as another observable. In other words, the outer observable emits the inner observables. Does it mean that we need to write nested subscribe() calls (one for the outer observable and another for the inner one)? No, we don’t. The flatMap() operator takes each item from the outer observable and auto-subscribes to it.

Some operators are not explained well in RxJS documentation, and we recommend you to refer to the general ReaciveX (reactive extensions) documentation for clarification. The flatMap() operator is better explained there, and it states that flatMap() is used to “transform the items emitted by an observable into observables, then flatten the emissions from those into a single observable”. This documentation includes the following marble diagram:

As you see, the flatMap() operator takes an emitted item from the outer observable (the circle) and unwraps its content (the inner observable of diamonds) into the flattened output observable stream. The flatMap() operator merges the emissions of the inner observables so their items may interleave.

The following code listing has an observable that emits drinks, but this time it emits not individual drinks, but palettes. The first palette has beers and the second – soft drinks. Each palette is observable. We want to turn these two palettes into an output observable with individual beverages.

function getDrinks() {

    let beers = Rx.Observable.from([   // 1
        {name: "Stella", country: "Belgium", price: 9.50},
        {name: "Sam Adams", country: "USA", price: 8.50},
        {name: "Bud Light", country: "USA", price: 6.50}
    ], Rx.Scheduler.async);

    let softDrinks = Rx.Observable.from([    // 2
        {name: "Coca Cola", country: "USA", price: 1.50},
        {name: "Fanta", country: "USA", price: 1.50},
        {name: "Lemonade", country: "France", price: 2.50}
    ], Rx.Scheduler.async);

    return Rx.Observable.create( observer => {
            observer.next(beers);     // 3
            observer.next(softDrinks);   // 4
            observer.complete();
        }
    );
}

// We want to "unload" each palette and print each drink info

getDrinks()
  .flatMap(drinks => drinks)    // 5   
  .subscribe(  // 6
      drink => console.log("Subscriber got " + drink.name + ": " + drink.price ),
      error => console.err(error),
      () => console.log("The stream of drinks is over")
  );

1. Creating an async observable from beers
2. Creating an async observable from soft drinks
3. Emitting the beers observable with next()
4. Emitting the soft drinks observable with next()
5. Unloading drinks from pallets into a merged observable
6. Subscribing to the merged observable

This script will produce the output that may look as follows (note that the drinks interleave):

Subscriber got Stella: 9.5
Subscriber got Coca Cola: 1.5
Subscriber got Sam Adams: 8.5
Subscriber got Fanta: 1.5
Subscriber got Bud Light: 6.5
Subscriber got Lemonade: 2.5
The stream of observables is over

To see it in CodePen visit this link.

Are there any other uses of the flatMap() operator besides unloading palettes of drinks? Another scenario where you’d want to use flatMap() is when you need to execute more than one HTTP request, where the result of the first request should be given to the second one. In Angular, HTTP requests return observables and without flatMap() this could be done (it a bad style) with nested subscribe() calls:

this.httpClient.get('/customers/123')
  .subscribe(customer => {
              this.httpClient.get(customer.orderUrl)
              .subscribe(response => this.order = response)
  })

The method httpClient.get() returns an observable, and the better way to write the above code is by using the flatMap() operator, which auto-subscribes and unwraps the content of the first observable and makes another HTTP request:

httpClient.get('./customers/123')
          .flatMap(customer => this.httpClient.get(customer.orderURL))
          .subscribe(response => this.order = response);

Since a flatMap() is a special case of map(), you can specify a transforming function while flattening the observables into a common stream. In the above example, we transform the value customer into a function call httpClient.get().

TIP: In RxJS, flatMap() is an alias of mergeMap() so these two operators have the same functionality.

Let’s consider one more example of using flatMap(). This example will be a modified version of the traders-orders example used in the article “Using RxJS Subject“. This example is written in TypeScript and it uses two Subject instances:

* traders – this Subject keeps track of traders
* orders – this Subject is declared inside the class Trader and keeps track of each order placed by a particular trader.

You’re the manager who wants to monitor all orders placed by all traders. Without flatMap(), you’d need to subscribe to traders (the outer observable) and create a nested subscription for orders (the inner observable) that each subject has. Using flatMap() allows you to write just one subscribe() call, which will be receiving the inner observables from each trader in one stream.

import {Subject} from 'rxjs/Subject';
import 'rxjs/add/operator/mergeMap';

enum Action{
    Buy = 'BUY',
    Sell = 'SELL'
}

class Order{
    constructor(public orderId: number, public traderId: number, public stock: string, public shares: number, public action:Action){}
}

let traders = new Subject<Trader>();  // 1

class Trader {

    orders = new Subject<Order>();   // 2

    constructor(private traderId:number, public traderName:string){}
}

let tradersSubscriber = traders.subscribe(trader => console.log(`Trader ${trader.traderName} arrived`))

let ordersSubscriber = traders        // 3
  .flatMap(trader => trader.orders)   // 4
  .subscribe(ord =>      // 5
       console.log(`Got order from trader ${ord.traderId} to ${ord.action} ${ord.shares} shares of ${ord.stock}`));

let firstTrader = new Trader(1, 'Joe');
let secondTrader = new Trader(2, 'Mary');

traders.next(firstTrader);
traders.next(secondTrader);

let order1 = new Order(1, 1,'IBM',100,Action.Buy);
let order2 = new Order(2, 1,'AAPL',200,Action.Sell);
let order3 = new Order(3, 2,'MSFT',500,Action.Buy);

// Traders place orders
firstTrader.orders.next( order1);
firstTrader.orders.next( order2);
secondTrader.orders.next( order3);

1. Declare the Subject for traders
2. Each trader has its own Subject for orders
3. Starting with the outer observable traders
4. Extracting the inner observable from each Trader instance
5. The function subscribe() receives a stream of orders

In this version of the program, the class Trader doesn’t have a method placeOrder(). We just have the trader’s observable orders push the order to its observer by using the method next(). Remember, a Subject has both observable and observer.

The output of this program is shown next.

Trader Joe arrived
Trader Mary arrived
Got order from trader 1 to BUY 100 shares of IBM
Got order from trader 1 to SELL 200 shares of AAPL
Got order from trader 2 to BUY 500 shares of MSFT

In our example, the subscriber just prints the orders on the console, but in a real world app it could invoke another function that would be placing orders with the stock exchange for execution.

To see it in CodePen, follow this link. In the next article you’ll learn about a very useful operator switchMap().

If you have an account at O’Reilly’s safaribooksonline.com, you can watch my video course “RxJS Essentials” there.

RxJS Essentials. Part 1: Basic terms

Today, I’m starting a series of articles about programming with reactive extensions. This series is about the JavaScript RxJS library, but in the future, I’m planning to write a similar series about the RxJava – one of the Java versions of reactive extensions.

The first library of reactive extensions (Rx) was created by Erik Mejier in 2009. Rx.Net meant to be used for the apps written using the Microsoft’s .Net technology. Then the Rx extensions were ported to multiple languages, and in the JavaScript world, RxJS 5 is the current version of this library.

Let’s see what being reactive means in programming by considering a simple example.

let a1 = 2;

let b1 = 4;


let c1 = a1 + b1;  // c1 = 6

 

This code adds the values of the variables a1 and b1, and c1 is equal 6. Now let’s add a couple of lines to this code modifying the values of a1 and b1:

let a1 = 2;

let b1 = 4;


let c1 = a1 + b1;  // c1 = 6

 

a1 = 55;       // c1 = 6 but should be 59 
    
b1 = 20;       // c1 = 6 but should be 75

While the values of a1 and b1 changed, c1 didn’t react to these changes and its value is still 6. Of course, you can write a function that adds a1 and b1 and invokes it to get the latest value of c1, but this would be an imperative style of coding where you dictate when to invoke a function to calculate the sum.

Wouldn’t it be nice if c1 would be automatically recalulated on any a1 or b1 changes? Think of any spreadsheet program like Microsoft Excel, where you could put a formula =sum(a1, b1) into the c1 cell, and c1 would react immediately on the changes in a1 and b1. In other words, you don’t need to click on any button to refresh the value of c1 – the data are pushed to this sell.

In the reactive style of coding (as opposed to imperative one), the changes in data drive the invocation of your code. Reactive programming is about creating responsive event-driven applications, where an observable event stream is pushed to subscribers, which observe and handle the events.

In software engineering, Observer/Observable is a well-known pattern, and it’s a good fit in any asynchronous processing scenario. But reactive programming is a lot more than just an implementation of the Observer/Observable pattern. The observable streams can be canceled, they can notify about the end of a stream, and the data pushed to the subscriber can be transformed on the way from the data producer to the subscriber by applying one or more composable operators (you’ll see some of them in Part 2 of this series).

Getting familiar with RxJS terminology

We want to observe data, which means that there is some data producer that can be a server sending data using HTTP or WebSockets, a UI input field where the user enters some data, an accelerometer in a smart phone, et al. An observable is a function (or an object) on the client that gets the producer’s data and pushes them to the subscriber(s). UI An observer is an object (or a function) that knows how to handle the data elements pushed by the observable.

Hot and cold observables

There are two types of observables: hot and cold. The main difference is that a cold observable creates a data producer for each subscriber, while a hot observable creates a data producer first, and each subscriber gets the data from one producer starting from the moment of subscription.

Let’s compare watching a movie on Netflix vs going into a movie theater. Think of yourself as an observer. Anyone who decided to watch “Mission Impossible” on Netflix will get the entire movie regardless of when he or she hit the button play. Netflix creates a new producer to stream a movie just for you. This is a cold observable.

If you go to a movie theater and the showtime is 4PM, “the producer is created” at 4PM and the streaming begins. If some people (subscribers) were late to the show, they missed the beginning of the movie and will watch it starting from the moment of arrival. This is hot observable.

A cold observable starts producing data when some code invokes a subscribe() function on it. For example, your app may declare an observable providing a URL on the server to get certain products. The actual request will be made only when you subscribe to it. If another script will make the same request to the server, it’ll get the same set of data.

A hot observable produces data even if there are no subscribers interested in the data. For example, an accelerometer of your smartphone produces multiple data about the position of your device even if there no app that subscribes to this data. Or a server can produce the latest stock prices even if no user is interested in this stock.

The main players of RxJS

The main players of RxJS are:

* Observable – data stream that pushes data over time
* Observer – consumer of an observable stream
* Subscriber – connects observer with observable
* Operator – a function for the en-route data transformation

I’ll introduce each of these players in this series by showing examples of their use. For a complete coverage, refer to RxJS documentation.

Observable, observer, and subscriber

As stated earlier, an observable gets data from some data source (a socket, an array, UI events) one element at a time. To be precise, an observable knows how to do three things:

* Emit the next element to the observer
* Throw an error on the observer
* Inform the observer that the stream is over

Accordingly, an observer object provides up to three callbacks:

* The function to handle the next element emitted by the observable
* The function to handle errors thrown by the observable
* The function to handle the end of stream

The subscriber connects an observable and observer by invoking the method subscribe() and disconnects them by invoking unsubscribe(). A script that subscribes to an observable has to provide the observer object that knows what to do with the produced elements. Let’s say we created an observable represented by the variable someObservable and the observer represented by the variable myObserver. Then you can subscribe to such an observable as follows:

let mySubscription: Subscription = someObservable.subscribe(myObserver);

To cancel the subscription, invoke the unsubscribe() method:

mySubscription.unsubscribe();

How an observable can communicate with the provided observer? It does it by invoking the following functions on the observer object:

* next() to push the next data element to the observer

* error() to push the error message to the observer

* complete() to send a signal to the observer about end of stream

You’ll see an example of using these functions in the next article of this series.

Creating observables

RxJS offers multiple ways of creating an observable depending on the type of the data producer. As an example, the data producer a DOM event, a data collection, a custom function, a WebSocket and more. Below are some examples of the API to create and observable:

* Observable.of(1,2,3) – turns the sequence of numbers into an Observable
* Observable.create(myObserver) – returns an Observable that can invoke
 methods on myObserver that you will create and supply as an argument
* Observable.from(myArray) – converts an array represented by the variable myArray into an Observable. You can also use any an iterable data collection or a generator function as an argument of from().
* Observable.fromEvent(myInput, ‘keyup’) – converts the keyup event from some HTML element represented by myInput into an Observable
* Observable.interval(1000) – emits a sequential integer (0,1,2,3…) every second

Let’s create an observable that will emit 1,2, and 3 and subscribe to this observable:

Rx.Observable.of(1,2,3) 
    .subscribe(
        value => console.log(value),
        err => console.error(err),
        () => console.log("Streaming is over")
);

Note that we pass three fat arrow functions to subscribe(). These three functions are the implementation of our observer. The first function will be invoked for each element emitted by the observable. The second function will be invoked in case of an error providing the object representing the error. The third function takes no arguments and will be invoked when the observable stream is over. Running this code sample will produce the following output on the console:

1
2
3
Streaming is over

To see it in action in CodePen, follow this link. Open the console view at the bottom to see the output.

The basic terms are covered. In the next article of this series, I’ll introduce you to some RxJS operators that are used to transform the emitted items while they’re moving from observable to the observer.

If you have an account at O’Reilly’s safaribooksonline.com, you can watch my video course “RxJS Essentials”.

TypeScript Generics

TypeScript supports parameterized types, also known as generics, which can be used in a variety of scenarios. For example, you can create a function that can take values of any type, but during its invocation, in a particular context, you can explicitly specify a concrete type.

Take another example: an array can hold objects of any type, but you can specify which particular object types (for example, instances of Person) are allowed in an array. If you were to try to add an object of a different type, the TypeScript compiler would generate an error.

Generics syntax

The following code snippet declares a Person class, creates two instances of it, and stores them in the workers array declared with the generic type. Generic types are denoted by placing them in the angle brackets (for example, ).

class Person {
    name: string;
}

class Employee extends Person{
    department: number;
}

class Animal {
    breed: string;
}

let workers: Array<Person> = [];

workers[0] = new Person();
workers[1] = new Employee();
workers[2] = new Animal();  // compile-time error

Here we declare the Person, Employee, and Animal classes and a workers array with the generic type. By doing this, we announce our plans to store only instances of the class Person or its descendants. An attempt to store an instance of an Animal in the same array will result in a compile-time error.

Nominal and Structural type systems

After using generics in Java for 10 years, I quickly noticed that the syntax is the same and was about to check off this syntax element as “got it”. But it was a little too soon. While Java, C++, or C# use nomimal type system, TypeScript uses the structural one. In the nominal system, types are checked against their names, but in a structural system by their structure.

With the nominal type system the following line would result in an error:

let person: Person = new Animal();

With a structural type system, as long as the structures of the type are similar, you may get away with assigning an object of one type to a variable of another. Let’s illustrate it by adding the property name to the class Animal as seen on the screenshot below.

Now the TypeScript compiler doesn’t complain about assigning an Animal object to the variable of type Person. The variable of type Person expects an object that has a property name, and the Animal object has it. This is not to say that Person and Animal represent the same types, but these types a compatible. Trying to assign the Person object to a variable of type Animal will result in the compilation error “Property breed is missing in type Person”:

let worker: Animal = new Person(); // compilation error

Can you use generic types with any object or a function? No. The creator of the object or function has to allow this feature. If you open TypeScript’s type definition file (lib.d.ts) on GitHub and search for “interface Array,” you’ll see the declaration of the Array, as shown below.

The <T> in line 1008 means TypeScript allows you to declare a type parameter with Array and the compiler will check for the specific type provided in your program. The next code listing specifies this generic <T> parameter as <Person>. But because generics aren’t supported in JavaScript, you won’t see them in the code generated by the transpiler. It’s just an additional safety net for developers at compile time.

You can see another T in line 1022 in figure B.7. When generic types are specified with function arguments, no angle brackets are needed. But there’s no actual T type in TypeScript. The T here means the push method lets you push objects of a specific type into an array, as in the following example:

workers.push(new Person());

Creating your own parameterized types

You can create your own classes or functions that support generics as well. In the next listing, we defined an interface Comparator that declares a method compareTo() expecting the concrete type to be provided during this method invocation.

interface Comparator {                   // 1
    compareTo(value: T): number;
}

class Rectangle implements Comparator {    // 2

    constructor(private width: number, private height: number){};

    compareTo(value: Rectangle): number{   // 3
        if (this.width*this.height &gt;= value.width*value.height){
            return 1;}
        else  {
            return -1;
        }
    }
}

let rect1:Rectangle = new Rectangle(2,5);  
let rect2: Rectangle = new Rectangle(2,3);

rect1.compareTo(rect2)===1? console.log("rect1 is bigger"): 
                            console.log("rect1 is smaller") ;   // 4


class Programmer implements Comparator {    // 5

    constructor(public name: string, private salary: number){};

    compareTo(value: Programmer): number{  // 6
        if (this.salary &gt;= value.salary){
            return 1;}
        else  {
            return -1;
        }
    }
}

let prog1:Programmer = new Programmer("John",20000);
let prog2: Programmer = new Programmer("Alex",30000);

prog1.compareTo(prog2)===1? console.log(${prog1.name} is richer):
                           console.log(${prog1.name} is poorer) ;  // 7

1. Declare an interface Comparator with a generic type

2. Create a class that implements Comparator specifying the concrete type Rectangle

3. Implement the method for comparing rectangles

4.Compare rectangles (the type T is erased and replaced with Rectangle)

5. Create a class that implement Comparator specifying the concrete type Programmer

6.Implement the method for comparing programmers

7. Compare programmers (the type T is erased and replaced with Programmer)

Even though generics are erased during the JavaScript code generation, use them to minimize the number of runtime errors. When you use libraries or frameworks written in TypeScript, you have no choice but use generics to use the API provided by these libraries.

If you live in New York, stop by at the Java SIG meetup on August 23, 2017 where I’ll be delivering a presentation “TypeScript for Java Developers”.