Typescript Foundations / Generics

Generic functions

Generics let you create functions (or classes, interfaces, etc.) that work with any type, while still retaining type safety.

Instead of hardcoding types, you define a placeholder type like <T>.


✅ Basic Syntax

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

const num = identity<number>(10);       // T = number
const str = identity<string>("hello");  // T = string

Here:

  • T is a generic type parameter.

  • TypeScript infers T if not explicitly provided.


🤖 With Type Inference

const result = identity("TypeScript"); // inferred as: string

🧮 Generic Function with Arrays

function getFirstElement<T>(arr: T[]): T {
  return arr[0];
}

getFirstElement([1, 2, 3]);         // number
getFirstElement(["a", "b", "c"]);   // string

🛠️ Multiple Type Parameters

function merge<T, U>(obj1: T, obj2: U): T & U {
  return { ...obj1, ...obj2 };
}

const merged = merge({ name: "Tisha" }, { age: 22 });
// inferred as: { name: string } & { age: number }

🔐 Constraints with extends

You can limit what types are allowed for the generic:

function logLength<T extends { length: number }>(item: T): number {
  return item.length;
}

logLength("hello");        // OK
logLength([1, 2, 3]);       // OK
logLength({ length: 5 });   // OK
// logLength(123);         ❌ Error: number doesn't have 'length'

📦 Generic with Default Type

function createBox<T = string>(value: T): T[] {
  return [value];
}

const box1 = createBox("hi");   // inferred as string[]
const box2 = createBox(42);     // inferred as number[]

🔄 Use in Arrow Functions

const wrapInArray = <T>(val: T): T[] => [val];

wrapInArray("apple");  // string[]
wrapInArray(true);     // boolean[]

🔍 Real-World Use Case

function fetchData<T>(url: string): Promise<T> {
  return fetch(url).then(res => res.json());
}

interface User {
  id: number;
  name: string;
}

fetchData<User>("/api/user").then(user => {
  console.log(user.name); // Type-safe access
});


📌 Summary

Concept

Description

<T>

Generic type placeholder

Inference

TypeScript guesses the type automatically

Constraints

T extends SomeType to restrict the input

Multiple Generics

<T, U> for combining multiple values

Defaults

<T = string> provides fallback types