Skip to main content

Generics

A core problem with strictly typed languages is maintaining powerful reusability. If you build a function designed strictly to return an Array of Numbers natively, you must tragically duplicate the entire function logic from scratch to process an Array of Strings cleanly.

Generics magically solve this by allowing you to establish a dynamic "Type Variable" natively!

Building a Generic

We define generic type variables systematically inside angle brackets <T>. T represents "Type", functionally acting as a temporary placeholder!

// Notice the <T>! It catches whatever type is explicitly passed to it natively!
function createArray<T>(item: T): T[] {
return [item];
}

// Usage: We pass the explicit strict type into the angle brackets!
const numberArray = createArray<number>(100);
// Results strictly in: number[]

const stringArray = createArray<string>("Hello");
// Results strictly in: string[]

Multi-Generic Parameters

We can map massive sprawling numbers of independent generics cleanly on a single function native instance.

function mergeMap<K, V>(key: K, value: V) {
return { key, value };
}

// We map a String key firmly against a Number value!
const newMap = mergeMap<string, number>("Speed", 120);
// Returns natively: { key: string, value: number }

Interface Generics

Generics pair gorgeously with Interfaces natively to produce highly scalable backend networking schemas natively.

// The Data wrapper is wildly dynamic!
interface APIResponse<T> {
status: number;
message: string;
data: T;
}

// Generating a strict User profile query response natively
const userResponse: APIResponse<{ name: string }> = {
status: 200,
message: "Success",
data: { name: "Alice" }
};