Sling Academy
Home/TypeScript/TypeScript Generic Array: A Complete Guide

TypeScript Generic Array: A Complete Guide

Last updated: January 07, 2024

Introduction

In the well-trod land of TypeScript, a versatile creation known as a generic array glimmers with the promise of type safety and flexibility. This guide offers to elucidate the mysteries of generic arrays, delivering ye an ample understanding of their potent capabilities through a cavalcade of code exemplars.

What are Generics?

Generics imbue TypeScript with the capacity to create components that can work over a variety of types rather than a single one. Imagine them as tools equally adept at carving both the hardy oak and the supple willow, with a precision that belies a tailor’s skill.

function getArray<T>(items : T[] ) : T[] {
    return new Array<T>().concat(items);
}

let numberArray = getArray<number>([1, 2, 3]);
let stringArray = getArray<string>(['hello', 'world']);

Basic Generic Array Usage

Our journey begins with the simplest manifestation of a generic array, one that moonlights as a repository for any type of artifact, from numbers to strings to the mysterious objects.

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

let output = identity('Mark Twain');  // output will be of type 'string'
console.log(output);

Generic Interfaces

As we progress, we shall encounter generic interfaces, steadfast contracts that bind the properties of our creations to our will.

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

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

let myIdentity: GenericIdentityFn<number> = identity;

Using Type Parameters

Next, type parameters take the stage, leading us to pen functions enlightened by the foresight of types known only in the murky future.

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

Generic Constraints

We then wade into the realm of constraints, where our generic types are not as unfettered as before, now bound by the attributes of another, as in a lively jig betwixt old friends.

interface Lengthwise {
    length: number;
}

function loggingIdentity<T extends Lengthwise>(arg: T): T {
    console.log(arg.length);  // This works now
    return arg;
}

The Specter of Handling Multiple Types

Indeed, our journey grows more thrilling yet, as we cast spells powerful enough to tame not one, but a dance of multiple differing types, swirling in harmony within a single function.

function combine<T, U>(arg1: T, arg2: U): [T, U] {
    return [arg1, arg2];
}

let result = combine(5, 'times');
console.log(result);  // Output: [5, 'times']

Working with Generic Classes

Before long, we heed the call of generic classes, where the principles we’ve hitherto grasped illuminate the path to creating structures flexible and resilient—a pantheon for variables of any genre.

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; };

Conditional Types and Arrays

In the twilight of our expedition, conditional types beckon us to open doors to deeper wisdom, where types change their guise like the capricious river, ever-dynamic, responsive to the input conveyed by our hands.

type StringOrNumber<T> = T extends number ? number[] : string[];

function process(arg: T): StringOrNumber<T> {
    if (typeof arg === 'number') {
        return [arg]; // number[]
    } else {
        return [arg.toString()]; // string[]
    }
}

Conclusion

As the last light fades on our sublime sojourn, remember that generics in TypeScript proffer, not just wisdom in the array of types, but an expanse that spurns the rigid for the dynamic. Abide by the principles laid forth, and traverse the type-filled lands with both confidence and grace.

Next Article: TypeScript Generic Function: A Complete Guide

Previous Article: Class vs Interface in TypeScript: Some Key Differences

Series: The First Steps to TypeScript

TypeScript

You May Also Like

  • TypeScript: setInterval() and clearInterval() methods (3 examples)
  • TypeScript sessionStorage: CRUD example
  • Using setTimeout() method with TypeScript (practical examples)
  • Working with window.navigator object in TypeScript
  • TypeScript: Scrolling to a specific location
  • How to resize the current window in TypeScript
  • TypeScript: Checking if an element is a descendant of another element
  • TypeScript: Get the first/last child node of an element
  • TypeScript window.getComputerStyle() method (with examples)
  • Using element.classList.toggle() method in TypeScript (with examples)
  • TypeScript element.classList.remove() method (with examples)
  • TypeScript: Adding Multiple Classes to An Element
  • element.insertAdjacentHTML() method in TypeScript
  • TypeScript – element.innerHTML and element.textContent
  • Using element.removeAttribute() method in TypeScript
  • Working with Document.createElement() in TypeScript
  • Using getElementById() method in TypeScript
  • Using Window prompt() method with TypeScript
  • TypeScript – window.performance.measure() method (with examples)