TypeScriptTypeScript12 min read

TypeScript Generics: A Practical Guide

Learn how to use TypeScript generics to write reusable, type-safe code.

Rachel Kim
December 2, 2025
14.2k568

Generics are one of the most powerful features in TypeScript. They allow you to write flexible, reusable code while maintaining type safety.

What are Generics?

Generics provide a way to create reusable components that work with multiple types rather than a single type. They allow you to define type variables that can be used throughout your code.

Generic Functions

Generic functions allow you to define functions that work with any type while preserving type information.

Generic Constraints

You can constrain generics to certain types using the extends keyword, ensuring that the generic type has certain properties or methods.

#TypeScript#Generics#Types#Advanced

Common Questions & Answers

Q1

What are generics in TypeScript and why are they useful?

A

Generics allow you to write reusable code that works with multiple types while maintaining type safety. They let you define type variables that are determined when the code is used, avoiding the need for type assertions or using any.

typescript
// Without generics (loses type information)
function identity(arg: any): any {
  return arg;
}

// With generics (preserves type information)
function identity<T>(arg: T): T {
  return arg;
}

const num = identity<number>(42);     // num is number
const str = identity<string>("hello"); // str is string
const auto = identity(true);          // TypeScript infers boolean
Q2

How do you constrain generics in TypeScript?

A

Use the extends keyword to constrain a generic type to types that have certain properties or extend certain interfaces. This ensures the generic type meets minimum requirements.

typescript
// Constraint: T must have a length property
interface Lengthwise {
  length: number;
}

function logLength<T extends Lengthwise>(arg: T): T {
  console.log(arg.length);
  return arg;
}

logLength("hello");      // OK: string has length
logLength([1, 2, 3]);    // OK: array has length
logLength({ length: 10 }); // OK: object has length
// logLength(42);        // Error: number doesn't have length

// Multiple constraints
function merge<T extends object, U extends object>(obj1: T, obj2: U) {
  return { ...obj1, ...obj2 };
}
Q3

How do you use generics with React components?

A

Generics in React components allow you to create reusable components that work with different data types while maintaining type safety for props.

typescript
// Generic List component
interface ListProps<T> {
  items: T[];
  renderItem: (item: T) => React.ReactNode;
  keyExtractor: (item: T) => string;
}

function List<T>({ items, renderItem, keyExtractor }: ListProps<T>) {
  return (
    <ul>
      {items.map(item => (
        <li key={keyExtractor(item)}>
          {renderItem(item)}
        </li>
      ))}
    </ul>
  );
}

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

const users: User[] = [{ id: 1, name: 'John' }];

<List
  items={users}
  renderItem={user => <span>{user.name}</span>}
  keyExtractor={user => user.id.toString()}
/>