How to design a Typescript Model for Response Returned By HttpClient library in Angular.

Vikash Singh
6 min readSep 30, 2018

--

Angular 4.3 Introduced us to HttpClient a new API to handle Http Requests with ample of new feautres .

Note:

The Older HttpModule is deprecated from Angular’s Version 4.3 so if you have not started using HttpClientModule yet it’s high time for you to switch to it.

Among all the newly introduced mind-boggling features which can be found here we are going to demystify how to Type check responses against your designed Model

Whats’s Type Checking in TypeScript means?

TypeScript is a strict syntactical superset of JavaScript and adds optional static typing to the language

In Static typing, type checking is done at compile-time.

Type Checking means Once you declare a variable to be a certain type, it’s the compiler job to ensure that it is only ever assigned values of that type (or values that are sub-types of that type).

example:

here foo is declared as type string and typescript throw a warning when a number is assigned to it.

Dead Simple ain’t it and in case if you want to dive in a bit deeper you can check this out.

next, let’s take a look at Typescript generics which makes it possible to type check the responses against your designed Model.

Generic types

In languages like C# and Java, one of the main tools in the toolbox for creating reusable components is generics, that is, being able to create a component that can work over a variety of types rather than a single one. This allows users to consume these components and use their own types.

https://www.typescriptlang.org/docs/handbook/generics.html

Here Component could be a method/class/interface.

Advantages of Generics:

  1. Code Reuse: We can write a method/class/interface once and use for any type we want.
  2. Type Safety: Generics make errors to appear at compile time than at runtime (It’s always better to know problems in your code at compile time rather than making your code fail at runtime).

Well, the definition is comprehensible yet bookish. In much simpler terms

Generics in TypeScript lets you parametrize type.

Let's work with an example to get a vivid picture.

The echo function is a function that will return back whatever is passed in Though it’s a contrived example, its good illustration for understanding generics.

Now the main question is how to type this function i.e. how to specify the return type and input argument type. After all, it’s typescript and it should be typed.

The first thing that would hit your mind is to type it as any because there are no restrictions on the type of input argument and return type.

Can you find the caveat in the current approach???

if echo(1) is called with a number it’s quite evident to the coder that it will return a number, But TypeScript does not know about the return type of echo(1) because echo is typed as any and moreover, typescript does not even complain when it is assigned to foo which is of type string .

How to enforce Typescript to complain about types in this scenario?

Well, Here is where typescript generics come into the play.

Generics features let’s you create a placeholder for the types that will later be replaced by a type argument when the generic type is instantiated and used. The instantiation of a generic type with actual type arguments is called a parameterized type.

Let’s make echo function generic the syntax is pretty simple.

function echo<T>(arg:T):T

Angle brackets (<>) next to function name makes the function generic.

The placeholder for the Type Involved is T(T is a common Convention ) with this Typescript knows that T is a placeholder for type information

The placeholder is used to declare the input argument (arg:T):T and the return type :T.

Typescript does not type check the input argument rather it takes the note of the input argument type when the function is called and when the execution is completed Typescript ensures that value returned from the function is of the same type as the type that was passed in.

In this case, when echo is called with a number as an input argument Typescript makes a note of it and when it sees that return type and input argument must be of the same type it throws a warning when the returned value is assigned to foo of type string .

Type Checking Http Response:

let’s assume the above data returned from the Server.

The subscribe callback above requires bracket notation to extract the data values.

You can’t write result.id because TypeScript correctly complains that the result object from the service does not have a id property.

Bracket notation and dot notation are functionally equivalent in JavaScript but are not the same thing in TypeScript. TypeScript is less strict with the bracket notation and this behavior is intentional to offer some kind of backdoor.

The HttpClient.get() method parsed the JSON server response into the anonymous Object type. It doesn't know what the shape of that object is.

You can tell HttpClient the type of response to make consuming the output easier and more obvious.

Approach:

First, define an interface with the correct shape:

Revised get method

Http returns an Observable and by type Checking, We can tell the HttpClient.get to return response as User type When we use http.get<User>(…) then it returns the instance of Observable<User> type. PlaceHolder, in this case, is User

Now we can write result.id because TypeScript is aware of the type of response.

Well, the next question is why to choose an interface over a class what is the advantage of using an interface over a class to design model?

A class is unsuitable for declaring a type that represents an HTTP response because the deserialized JSON values that result from HTTP requests will never be instances of a class. An interface is perfect candidate for it.

Class vs Interface

Classes and interfaces are powerful structures that facilitate not just object-oriented programming but also type-checking in TypeScript. A class is a blueprint from which we can create objects that share the same configuration properties and methods. An interface is a group of related properties and methods that describe an object, but neither provides implementation nor initialization for them.

Since both of these structures define what an object looks like, both can be used in TypeScript to type our variables. The decision to use a class or an interface truly depends on our use case: type-checking only, implementation details (typically via creating a new instance), or even both! We can use classes for type-checking and the underlying implementation

https://toddmotto.com/classes-vs-interfaces-in-typescript

Since we are interested only in type-checking the responses Interface is a good choice because the response text will be deserialized into plain JavaScript objects. Furthermore, an interface is a virtual structure that only exists within the context of TypeScript. The TypeScript compiler uses interfaces solely for type-checking purposes. Once your code is transpiled to its target language, it will be stripped from its interfaces - JavaScript isn’t typed, there’s no use for them there.

Since interfaces do not exist in runtime there is no runtime cost!

--

--

Vikash Singh

Senior Software Engineer at CoindDCX. Angular Enthusiast.