About Generics Type in Typescript

I will write this to understand type deeply. I referred to Generics type in Typescript

What is generics type?

Simply speaking, it enable us to create a component that can work over a variety of types rather than a single one, so I can consume these components and fuse their own types.

Hello world of Generics

To study this type, I would write the identity function.

what is the identity function? :

In mathematics, an identity function, also called an identity relation or identity map or identity transformation, is a function that always returns the same value that was used as its argument. by wikipedia

That is, it is like $ echo.

If generics didn't exist

We have to give the function a specific type:

function identity(arg: number): number {
    return arg;
}

or we could use any like below.

function identity(arg: any): any {
    return arg;
}

In this case above, the identity function can accept all types for the types of arg but we lost the information about what that types was when the function returns. If we passed in a number, the only information we have is that any type could be returned.

Instead of setting specific types, we use generics

By using generics, we can make the function accept a type variable , a special kind of variable that works on types rather than values.

function identity<T>(arg: T): T {
    return arg;
}

T in the code above is an example, so you can any name for a generics type. But it is conventional to use T which I think stands for Type.

If you want set type exactly, write like this.

let output = identity<string>("myString");  // type of output will be 'string'

It is all right that a generic type is empty. The type of a value you pass in () is automatically applied.

let output = identity("myString");  // type of output will be 'string'

However it is possible to fail, in that moment you should explicit the generics type.

Working with Generic Type Variables

Generics type can accept all type, so the complier treat the type as if it was any and all types.

function loggingIdentity<T>(arg: T): T {
    console.log(arg.length);  // Error: T doesn't have .length
    return arg;
}

That is because all types don't have .length, for example number.

If you want to get the length of arg in generics function, you can combine the generics type with Array.

function loggingIdentity<T>(arg: T[]): T[] {
    console.log(arg.length);  // Array has a .length, so no more error
    return arg;
}

Another example like this.

function loggingIdentity<T>(arg: Array<T>): Array<T> {
    console.log(arg.length);  // Array has a .length, so no more error
    return arg;
}

we can assign a generic function to a function that have a different name generic type like below.

function identity<T>(arg: T): T {
    return arg;
}

let myIdentity: <U>(arg: U) => U = identity;

We move the generic parameter to be a parameter of the whole interface and the n can see like below. That makes the generic type visible to all the other members of the interface.

interface GenericIdentityFn<T> {
    (arg: T): T;
}

function identity<T>(arg: T): T {
    return arg;
}

let myIdentity: GenericIdentityFn<number> = identity;

Generic Classes

You can create a generic class. But It is not possible to create generic enums and namespaces.

class GenericNumber<T> {
    zeroValue: T;
    add: (x: T, y: T) => T;
}

let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function(x, y) { return x + y; };

let stringNumeric = new GenericNumber<string>();  // Of course it is possible to assign string type to it.
stringNumeric.zeroValue = "";
stringNumeric.add = function(x, y) { return x + y; };

console.log(stringNumeric.add(stringNumeric.zeroValue, "test"));

Vocabulary

  • denote: be a sign of; indicate.
    this mark denotes purity and quality

  • enforce : compel observance of or compliance with (a law, rule, or obligation).
    the role of the police is to enforce the law

  • compel : force or oblige (someone) to do something.
    a sense of duty compelled Harry to answer her questions

  • generically : in a way that relates to a class or group of similar things; not specifically.
    what most writers generically refer to as ‘world music

  • restrict : put a limit on; keep under control.
    some roads may have to be closed at peak times to restrict the number of visitors