Learn Typescript Generics with examples

TypeScript Functions and Generics

Functions contain reusable code with arguments and return types.

Let’s declare a function that takes a string and returns a string.

function getMessage(msg: string): string {
  return msg;
}

console.log(getMessage("john"));

The above function only works with string arguments. If you want to pass other types, such as a number, you would need to write a new function.

function getMessage(msg: number): number {
  return msg;
}
console.log(getMessage("john")); //Argument of type 'string' is not assignable to parameter of type 'number'.(2345)

console.log(getMessage(123)); //123

Another approach is to write a function that accepts any type.

function getMessage(msg: any): any {
  return msg;
}

console.log(getMessage("john"));
console.log(getMessage(1.5)); // 1.5

To avoid having multiple functions for different types, we can define a generic function.

The argument is declared with type T, and the return type is also declared with T. The function name is annotated with the generic <T> type.

function getMessage<T>(msg: T): T {
  return msg;
}

console.log(getMessage<string>("john")); // john
console.log(getMessage<number>(1.5)); // 1.5

TypeScript Arrow Functions with Generics

Let’s explore generic arrow functions in TypeScript.

const getMessage = <T>(value: T) => {
  return value;
};
let number = getMessage<number>(100);
let name = getMessage<string>("Hello");

Interface Generics

Let’s create an interface for an array of numbers.

interface ArrayNumbers{
    add(value: number): number;
}

Next, let’s declare an interface for an array of strings.

interface ArrayOfStrings {
    add(value: string) : string;
}

To avoid declaring an interface for each type, we can write a generic interface.

interface Array<T> {
    add() : T;
}

Advantages of TypeScript Generics

Reuse code for multiple types instead of declaring code for each type.