6) Typescript Generics
Generic Functions
Generics in TypeScript allow you to create reusable, type-safe components, functions, hooks, and interfaces without hardcoding types. They help React developers build: reusable UI components, reusable hooks, strongly typed APIs, scalable code-bases.
A generic function works with multiple data types while preserving type safety.
Examplefunction identity<T>(value: T): T { return value; } const str = identity<string>("Hello"); const num = identity<number>(100); console.log(str); console.log(num);Why Use Generic Functions?
Without generics,function identity(value: any): any { return value; }Problem:
i) Loses type safety
ii) No autocomplete
iii) No compile-time validation
Generics solve this.
Generic Function with Arraysfunction getFirstElement<T>(arr: T[]): T { return arr[0]; } const firstNumber = getFirstElement([1, 2, 3]); const firstString = getFirstElement(["A", "B", "C"]);TypeScript automatically infers types.
React Examplefunction filterItems<T>( items: T[], predicate: (item: T) => boolean ): T[] { return items.filter(predicate); } const users = [ { id: 1, name: "Rahul" }, { id: 2, name: "Amit" }, ]; const result = filterItems(users, user => user.id === 1);Multiple Generic Types
function merge<T, U>(obj1: T, obj2: U): T & U { return { ...obj1, ...obj2 }; } const result = merge( { name: "Rahul" }, { age: 30 } ); console.log(result.name); console.log(result.age);Generic Interfaces
Generic interfaces define reusable structures.interface ApiResponse<T> { success: boolean; data: T; message: string; } interface User { id: number; name: string; } const response: ApiResponse<User> = { success: true, data: { id: 1, name: "Rahul", }, message: "Success", };Generic Interface with Arrays
const users = [ { id: 1, name: "Rahul" }, { id: 2, name: "Amit" }, ]; export default function App() { return ( <List items={users} renderItem={(user) => ( <div>{user.name}</div> )} /> ); }Generic Constraints
Constraints restrict what types can be used. Without constraints, TypeScript allows any type.
Why Constraints?
Suppose you want to access the.lengthfunction printLength<T>(value: T) { console.log(value.length); // ERROR }TypeScript doesn't know if
Thaslength.function printLength<T extends { length: number }>(value: T) { console.log(value.length); }