Cool features of Generics in TypeScript

<em>Generics</em>&nbsp;is not a new term in today’s programming world. Most of the programming language has this feature. Today, we are going to learn about Generics in TypeScript. It is very easy, and powerful feature of any programming language.

Generics

Generics is not a new term in today’s programming world. Most of the programming language has this feature. Today, we are going to learn about Generics in TypeScript. It is very easy, and powerful feature of any programming language.

What is Generic?

Like functions, generics are also another kind of function for variable types. Normally, we create functions to reuse it in multiple places of your program. OR you can say, functions are used for any repeated tasks.

Generics also do the same thing, but in a little different manner. Using generics, we make a generalized function for different data types, instead of creating separate functions for each data type. You can define Generic classes, interfaces and functions in TypeScript. These all can work with different data types using the concept of Type Parameters.

What is Type Parameters?

Type parameter is used to define the data type of any parameters of generic class or interface. Generally, type parameter is denoted by T or <T> in any generic class, function and interface. You can use any other alphabet to denote the type parameter.

Generic Function

function funcName<T>(arg : T) : T {
    //function Code
    return arg
}

In the above example, you can see, we have created a generic function funcName, along with type parameter T. We are also mentioning the return type using T in the syntax. We can pass any data type in the function.

Calling the generic function with string type

let output = funcName<string>("Hello Adesh");

Here, we call the function with string type, and get the same type in the return.

Calling the generic function with number type

let output = funcName<number>(100);

Again, we called the same function, with number data type, and get the same type in the return.

So, in both function calling, our generic function worked well for both type parameters of string and number. It didn’t break any code and it is totally type-safe as well.

Generic Class

Like Generic functions, we can create Generic Classes using the type parameter T. Our generic class can work with different data type. Let’s create a generic class and pass the string and number data type values. For eg.

class TestGeneric<T> {
    private genericVal: T;
    setVal(x: T): void {
        this.genericVal = x;
    }
    getVal(): T {
        return this.genericVal;
    }
}

Call our generic class by string

let strVal = new TestGeneric<string>();
strVal.setVal("hello Adesh");
alert(strVal.getVal());

Call our generic class by number

let numVal = new TestGeneric<number>();
numVal.setVal(100);
alert(numVal.getVal());

Generic Interface

We can create Generic Interface in TypeScript. The following are the examples of generic interface.

Generic Interface as Type
interface IExample<T, U> {
    Id: T,
    Value: U
}
 
let Example1: IExample<number, string> = {Id: 1, Value: 'Test'};
let Example2: IExample<number, number> = {Id: 2, Value: 100};

The IExample is generic type. Here, we are passing two type parameters T & U. Example1 is passing number and string to generic type. Example2 is passing number and number to generic type.

Generic Interface as Function Type
interface IKeyValuePair<T, U>
{
    (key: T, value: U): void;
};
 
function NumKeyPairs(key:number, value:number):void { 
    console.log('Example 1: key = ' + key + ', value = ' + value)
}
 
function StrKeyPairs(key: number, value:string):void { 
    console.log('Example 2: key = '+ key + ', value = ' + value)
}
    
let numKeyValue: IKeyValuePair<number, number> = NumKeyPairs;
numKeyValue(1, 100); //Output: Example 1: key = 1, value = 100 
 
let strKeyValue: IKeyValuePair<number, string> = StrKeyPairs;
strKeyValue(1, "Adesh"); //Output: Example 2: key = 1, value = Adesh

In the above example, we have created a generic interface IKeyValuePair, which includes the generic method without the method name. We can use any function, which match the signature of our generic method of interface.

We have two functions, NumKeyPairs & StrKeyPairs, which has matching signature with our generic method of generic interface. Later, we set the generic types, while creating the variables numKeyValue & strKeyValue.

If you look at the above code, we can also generalized these two functions NumKeyPairs & StrKeyPairs as well. This generalization of functions will reduce our overall code and make it concise implementation.

Generalized version of above code
interface IKeyValuePair<T, U>
{
    (key: T, value: U): void;
};
 
function funcKeyValuePairs<T, U>(key:T, value:U):void { 
    console.log(`key = ${key}, value = ${value}`)
}
    
let numKeyValue: IKeyValuePair<number, number> = funcKeyValuePairs;
numKeyValue(1, 100); //Output: key = 1, value = 100 
 
let strKeyValue: IKeyValuePair<number, string> = funcKeyValuePairs;
strKeyValue(1, "Adesh"); //Output: key = 1, value = Adesh

As you can see, we have removed functions NumKeyPairs & StrKeyPairs, and created a generic function funcKeyValuePairs. Now, there is no need to create two separate functions. Then, we set the new generalized function funcKeyValuePairs to both variables numKeyValue & strKeyValue.

Generic Interface implementation in Class

We can implement generic interface in a class, same as other non-generic interface.

interface IKeyValuePair<T, U>
{
    printKeyValue(key: T, val: U): void;
};
 
class clsKeyValue implements IKeyValuePair<number, string>
{ 
    printKeyValue(key:number, val:string):void { 
        console.log(`Key = ${key}, val = ${val}`);
    }
}
 
let clsObj: IKeyValuePair<number, string> = new clsKeyValue();
clsObj.printKeyValue(1, 'Adesh'); //Output: key = 1, value = Adesh

Here, we have created a class clsKeyValue, and implements the generic interface IKeyValuePair. We set the generic type parameters while creating the object of the class. This class will implement the generic method printKeyValue of generic interface.

Generic Constraints

Sometimes, we don’t want to create our generic classes, functions and interfaces for all data type parameters, or put some specific requirements/constraints. In our below example, we are going to create a function, where the passing parameters much have an Id property. Let’s see, how can we achieve this using the Generic Constraints.

interface IdRequired {
    Id: number;
}
 
function funcKeyValue<T extends IdRequired>(arg: T): T {
    alert(arg.Id);  
    return arg;
}

Here, for function funcKeyValue, an Id must be required. To achieve this requirement, we have created an interface IdRequired, and extend our function with this interface. Now, let’s see, what will happen when we pass this parameter in the function.

let val = funcKeyValue(3); //Show an error message and alert the undefined value

Above code will show an error message, and alert the undefined value. Because, there is no Id property passed to the function. So, what is the proper way of calling the above function.

let val = funcKeyValue({Id:1, name: 'Adesh'});

This is the right way of calling our function. This call has an Id property, and our function will work properly. It will not show any error message.

So, we see, how we achieved generic constraints using interfaces.

Summary

In this blog, I we learned about generics, different kind of its implementation with functions, classes and interfaces. We learned about how to avoid writing the duplicate code, and make our program concise and type-safe as well. Generics improves the code reusability and encapsulation.

I hope you enjoyed a lot reading this post.


By : Adesh


Learn TypeScript | TypeScript Crash Course | TypeScript Tutorial for Beginners

Learn TypeScript | TypeScript Crash Course | TypeScript Tutorial for Beginners

Learn TypeScript | TypeScript Crash Course | TypeScript Tutorial for Beginners: My goal with this courses is just give your the fundamentals of the language, show you what TypeScript is and how to use it. We as developers don't have time neither can we afford to spend too much time on any tehcnology.

TypeScript is a superset of JavaScript, which means that is language that was created to add features to JavaScript. You might be asking yourself why it was created and why not just add those features directly to JavaScript.

Sometimes language foundatons take time to implement features because the committee has to approve it, test and get feedback before requests are answered. The soultion for that is to create another language that adds functionality to the language we need, and thats where TypesScript comes in.

TypeScript has many advanced features that plain JavaScript doesnt have yet but the good news is that we can start using it now since TypeScript compiles JavaScript ES5 which at this moment is the most compatible version of JavaScript for all browsers.

Most people that want to learn TypeScript its because they need the skills to use with some Frameworks like Angular.

My goal with this courses is just give your the fundamentals of the language, show you what TypeScript is and how to use it. We as developers don't have time neither can we afford to spend too much time on any tehcnology.

Thanks for reading

If you liked this post, please do share/like it with all of your programming buddies!

Follow us on Facebook | Twitter

Further reading about JavaScript and TypeScript

The Complete JavaScript Course 2019: Build Real Projects!

Vue JS 2 - The Complete Guide (incl. Vue Router & Vuex)

JavaScript Bootcamp - Build Real World Applications

The Web Developer Bootcamp

New ES2019 Features Every JavaScript Developer Should Know

Best JavaScript Frameworks, Libraries and Tools to Use in 2019

Using Typescript with modern React (i.e. hooks, context, suspense)

WebSocket + Node.js + Express — Step by step tutorial using Typescript

From Javascript to Typescript to Elm

Angular + Typescript = Powerful Web Apps

React + TypeScript : Why and How

How to use TypeScript with Vue.js

Introduction To TypeScript

Some tools are so useful that once you've used them in one project, it is hard to work on other projects without them. React was certainly that way for me when I first started, and now TypeScript has become the same way. This talk will cover why typed JavaScript, especially in large codebases, is worth the added effort. I will discuss my personal experiences - the good, the bad, and the ugly - and talk about why I can't seem to start a project without <code>npm install typescript</code>.

Some tools are so useful that once you've used them in one project, it is hard to work on other projects without them. React was certainly that way for me when I first started, and now TypeScript has become the same way. This talk will cover why typed JavaScript, especially in large codebases, is worth the added effort. I will discuss my personal experiences - the good, the bad, and the ugly - and talk about why I can't seem to start a project without npm install typescript.


Learn more


Understanding TypeScript

http://learnstartup.net/p/HkVUp2y8e

Typescript Masterclass & FREE E-Book

http://learnstartup.net/p/BJKmIUFP2g

Angular Tutorial: Create a CRUD App with Angular CLI and TypeScript

http://dev.thegeeknews.net/0774add31e

Introduction to TypeScript Development

http://learnstartup.net/p/HyEiI-lWx

6 Essential VSCode Extensions for Angular Developers

http://go.learn4startup.com/8d20682b41

Angular Essentials (Angular 2+ with TypeScript)

http://learnstartup.net/p/SkdU19JFZ

Backend API with Node, Express & TypeScript - Fast Track

http://learnstartup.net/p/rtgZjWg_g

Learn Protractor(Angular Automation) from scratch +Framework

http://learnstartup.net/p/fiGYxoVhe