
TypeScript Advanced Patterns for Professional Developers
Md Nayeem Hossain
Author
Md Nayeem Hossain
Author
TypeScript Advanced Patterns
Most developers know the basics of TypeScript: strings, numbers, and interfaces. But TypeScript's type system is incredibly powerful (Turing complete, actually!). Mastering advanced patterns allows you to write libraries and utilities that are robust and flexible.
Generics: Flexible Reusable Code
Generics allow you to write code that works with a variety of types rather than a single one. Think of them as "variables for types."
// Without generics, we lose type information
function getFirst(arr: any[]) {
return arr[0]; // Return type is 'any'
}
// With generics
function getFirst<T>(arr: T[]): T | undefined {
return arr[0];
}
const num = getFirst([1, 2, 3]); // Type is 'number'
const str = getFirst(["a", "b"]); // Type is 'string'Utility Types
TypeScript comes with built-in utilities that transform types.
Partial<T>: Makes all properties optional.Pick<T, K>: Selects a subset of properties.Omit<T, K>: Removes a subset of properties.interface User {
id: number;
name: string;
email: string;
passwordHash: string;
}
// When updating a user, we might only provide some fields
type UpdateUserDto = Partial<User>;
// When displaying a user, we NEVER want to show the password
type UserProfile = Omit<User, 'passwordHash'>;Discriminated Unions
This is my favorite pattern for state management (like in Redux or useReducer). It uses a common literal field (usually type or kind) to let TypeScript narrow down the type.
type APIState =
| { status: "loading" }
| { status: "success"; data: User[] }
| { status: "error"; error: string };
function handleState(state: APIState) {
if (state.status === "loading") {
// TypeScript knows 'data' and 'error' don't exist here
return "Loading...";
}
if (state.status === "success") {
// TypeScript knows 'data' exists here!
return `Loaded ${state.data.length} users`;
}
if (state.status === "error") {
return `Error: ${state.error}`;
}
}This pattern makes "impossible states" impossible to represent in your code, eliminating entire classes of bugs.


