Generic Implementation

Tutorial 2 of 4

Generic Implementation in TypeScript: A Beginner's Guide

1. Introduction

Goal

In this tutorial, we will learn how to implement generic types using TypeScript in an HTML environment.

What You Will Learn

You will learn about TypeScript generics, why they are important, and how to implement them in your code.

Prerequisites

To get the most out of this tutorial, you should have a basic understanding of TypeScript and HTML.

2. Step-by-Step Guide

TypeScript Generics is a tool for creating reusable components. A component can be a function, class or interface.

Why do we need Generics?

In TypeScript, we sometimes want to write software components that can work over a variety of types rather than a single one. This can help maintain type safety while allowing for more flexible (and reusable) code.

Concept Explanation with Examples

Here's a simple function that returns the argument it receives:

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

But what if we want our function to work with different types of arguments?

You might think of using the any type:

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

But if we do this, we lose the information about what that type was when the function returns. This is not ideal.

This is where Generics come in. Let's modify the above function to use generics:

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

In this snippet, we added a type variable T to our function. T captures the type of the argument, so we can use it again as the return type.

3. Code Examples

Example 1: Simple Generic Function

// Here is a function that uses generics.
function identity<T>(arg: T): T {
  return arg;
}

let output = identity<string>("myString");
console.log(output);

Here, we're explicitly stating that we want to use the version of identity that works with strings. The <string> part is the type argument, and it's used to specify the type we want our function to use.

Expected Output

"myString"

Example 2: Generic Array

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

Here, we're saying that the loggingIdentity function takes an argument arg that is an array of some type T, and returns an array of the same type T.

4. Summary

In this tutorial, we've learned about TypeScript generics and how they can help us create reusable, flexible, and type-safe code. We've seen how to implement generics in functions and learned about generic arrays.

5. Practice Exercises

Exercise 1

Write a generic function reverse that reverses an array of any type.

function reverse<T>(items: T[]): T[] {
  // Your code here
}

Solution

function reverse<T>(items: T[]): T[] {
  return items.reverse();
}

This function will work with an array of any type - strings, numbers, booleans, etc. The reverse function is a method that is available on all JavaScript arrays, so we can use it here without any issues.

Exercise 2

Create a generic class GenericNumber that has a zero value and an add function. Implement it for the number type.

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

Solution

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

  constructor(zeroValue: T, add: (x: T, y: T) => T) {
    this.zeroValue = zeroValue;
    this.add = add;
  }
}

let myGenericNumber = new GenericNumber<number>(0, function(x, y) { return x + y; });
console.log(myGenericNumber.add(3, 4)); // Outputs 7

In this example, the GenericNumber class works with any type T, not just numbers. We've used it with the number type, but it could be used with any type.

Remember, practice makes perfect. Keep using generics in your TypeScript code to get more comfortable with them. Happy coding!