TypeScript Generics and Built-in Utility Types#
In senior-level TypeScript interviews, candidates are often asked:
What are TypeScript Generics, and how do built-in utility types like
Omit,Pick, andReturnTypework under the hood?
To answer this, you must demonstrate your understanding of type parameters, mapped types, and conditional types.
1. What Are Generics?#
Generics allow you to write reusable, type-safe components or functions that work with a variety of types rather than a single one. They act as type variables passed to functions, classes, or aliases.
Example of a type-safe API client helper:
interface ApiResponse<T> {
data: T;
status: number;
success: boolean;
}
interface User {
id: string;
name: string;
}
// The generic type User is passed to ApiResponse
const response: ApiResponse<User> = {
data: { id: "123", name: "Alice" },
status: 200,
success: true
};
2. Understanding Built-in Utility Types#
TypeScript provides global utility types to help manipulate object and function types. Let's look at how they are defined internally.
A. Pick<T, K>#
Constructs a type by picking a set of properties K from T.
- Under the hood:
TYPESCRIPT
type Pick<T, K extends keyof T> = { [P in K]: T[P]; };
B. Omit<T, K>#
Constructs a type by picking all properties from T and then removing keys in K.
- Under the hood (uses
Exclude):TYPESCRIPTtype Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
C. ReturnType<T>#
Extracts the return type of a function type T.
- Under the hood (uses conditional types and the
inferkeyword):TYPESCRIPTtype ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
3. Conditional Types & The infer Keyword#
Conditional types allow you to declare types that choose their structure based on a condition:
SomeType extends OtherType ? TrueType : FalseType
The infer keyword can only be used inside the conditional check of a conditional type. It tells TypeScript to infer a type parameter dynamically at compile time and make it available in the true branch.
Key Takeaways#
- Generics: Write code that remains flexible while maintaining strict compile-time types.
- Utility Types: Standard utilities like
PickandOmituse mapped types under the hood to transform object shapes. - infer Keyword: Allows you to extract type parameters out of functions, arrays, and promises dynamically.