Suleman Ahmed - BlogMastering TypeScript Generics: Writing Reusable Type-Safe Code

TypeScript has become the standard for modern web development, and generics are one of its most powerful features. Generics allow us to design components and helper functions that work with multiple types instead of a single one.

Why Use Generics?

Without generics, if we want to write a function that accepts an argument and returns it, we would have to use `any` or duplicate the code. Generics let us capture the type of the argument provided by the user, assuring type-safety and developer autocomplete.

Creating a Generic Fetching Utility

Let's write a wrapper around fetch that returns typed responses:

utils/api.tstypescript
export async function apiRequest<T>(url: string, options?: RequestInit): Promise<T> {
  const response = await fetch(url, options);
  
  if (!response.ok) {
    throw new Error(`HTTP error! status: ${response.status}`);
  }
  
  const data = await response.json();
  return data as T;
}

Now let's use this generic function in our code:

typescript snippettypescript
interface User {
  id: number;
  name: string;
  email: string;
}

async function fetchUser(userId: number) {
  try {
    // TypeScript automatically infers that user is of type User
    const user = await apiRequest<User>(`https://api.example.com/users/${userId}`);
    console.log(`User: ${user.name} (${user.email})`);
  } catch (error) {
    console.error('Failed to fetch user:', error);
  }
}

Generic Constraints

Sometimes we want to limit the types that a generic parameter can accept. We can do this using the `extends` keyword.

typescript snippettypescript
interface HasId {
  id: string | number;
}

// T must contain an id property
function logItemDetails<T extends HasId>(item: T): void {
  console.log(`Logging item with ID: ${item.id}`);
}

Generics are essential to write scalable, robust code in larger codebases, reducing duplicated interfaces and preserving strict type compliance.

© 2026 Suleman Ahmed. All rights reserved.

Built with Next.js, Tailwind CSS & Sanity.