Reusable Type Modeling with Generics
Use generics to model real-world patterns like typed collections, enriched objects, and reusable response structures without losing type safety.
Learning generics isn’t just about angle brackets and type placeholders. It’s about building systems—clean, scalable type systems that reflect our app’s logic.
TypeScript is especially effective when we start designing reusable type models: tools we can apply repeatedly across features, APIs, and domains. This is what the current lesson covers.
Let’s first get familiar with the generic types that come built into TypeScript.
Introducing built-in generic types
We’ve used arrays, promises, and objects in JavaScript for years. But in TypeScript, each of these has a typed, generic counterpart that gives you precision and predictability. These generic counterparts let us describe the kind of values we’re working with—not just that we have a list or a promise, but what’s inside it.
Let’s look at a few of the most common ones in action.
const names: Array<string> = ["Alex", "Jordan", "Sam"];const settings: Record<string, boolean> = {darkMode: true,notifications: false,};const userIds: Promise<number[]> = Promise.resolve([1, 2, 3]);console.log(`Names: ${names.join(", ")}`);console.log(`Dark Mode: ${settings.darkMode}, Notifications: ${settings.notifications}`);userIds.then(ids => console.log(`User IDs: ${ids.join(", ")}`));
Explanation:
Line 1:
Array<T>
ensures that every element in the array is aT
. Here,names
can only contain strings.Line 2:
Record<K, V>
defines an object where all keys (K
) map to values of typeV
. Here, all keys arestring
, all values areboolean
.Line 6:
Promise<T>
describes the type ...