Back to Blog
TypeScript6 min read

Mastering TypeScript Generics: A Practical Guide

Mastering TypeScript Generics: A Practical Guide

TypeScript generics enable you to write flexible, reusable code while maintaining type safety. Let's dive into practical examples that you can apply immediately.

Understanding the Basics

At its core, a generic is a type placeholder. Think of it as a variable, but for types:

function identity<T>(arg: T): T {

return arg;

}

// T becomes 'string'

const str = identity("hello");

// T becomes 'number'

const num = identity(42);

Constraining Generics

Sometimes you need to ensure the generic type has certain properties:

interface HasLength {

length: number;

}

function logLength<T extends HasLength>(arg: T): T {

console.log(arg.length);

return arg;

}

Generic Utility Types

TypeScript provides powerful built-in utility types:

// Make all properties optional

type PartialUser = Partial<User>;

// Make all properties required

type RequiredUser = Required<User>;

// Pick specific properties

type UserName = Pick<User, 'firstName' | 'lastName'>;

Real-World Patterns

Here's a pattern I use frequently for API responses:

interface ApiResponse<T> {

data: T;

status: number;

message: string;

}

async function fetchData<T>(url: string): Promise<ApiResponse<T>> {

const response = await fetch(url);

return response.json();

}

Conclusion

Generics are essential for writing maintainable TypeScript. Start simple, and gradually incorporate more advanced patterns as you become comfortable.

Enjoyed this article? Share it with others.