CHALLENGE 2: Generic Cache Class ================================== SOLUTION: class Cache { private value: T; constructor(initialValue: T) { this.value = initialValue; } get(): T { return this.value; } set(newValue: T): void { this.value = newValue; } } // Testing with different types: // Cache for a string const stringCache = new Cache("initial value"); console.log(stringCache.get()); // "initial value" stringCache.set("updated"); console.log(stringCache.get()); // "updated" // Cache for a number const numberCache = new Cache(42); console.log(numberCache.get()); // 42 numberCache.set(100); console.log(numberCache.get()); // 100 // Cache for an object interface User { id: number; name: string; } const userCache = new Cache({ id: 1, name: "Alice" }); console.log(userCache.get().name); // "Alice" userCache.set({ id: 2, name: "Bob" }); console.log(userCache.get().name); // "Bob" // Type Safety Example: const cache = new Cache("hello"); const value = cache.get(); // TypeScript knows value is 'string' console.log(value.toUpperCase()); // ✅ Safe: strings have toUpperCase() EXPLANATION: - "class Cache { }" — the class is generic, can hold any type - "private value: T" — the stored value is of type T - "constructor(initialValue: T)" — initializes the cache with a T value - "get(): T" — returns the cached value (as type T) - "set(newValue: T): void" — updates the cache with a new T value WHY GENERIC CLASSES ARE USEFUL: - Containers/wrappers that hold any type (Cache, Box, Container) - Collections with type safety (List, Stack, Queue) - API responses (ApiResponse where T is the data type) - State management (Store in React/Vue patterns) ALTERNATIVE: With Type Inference (constructor shorthand) class Cache { constructor(private value: T) {} get(): T { return this.value; } set(newValue: T): void { this.value = newValue; } } This is more concise: the 'private value: T' in the constructor automatically creates and initializes the property. USING TYPE INFERENCE: You can also let TypeScript infer the type: const cache = new Cache("hello"); // T is inferred as 'string' // Instead of: const cache = new Cache("hello"); Both work, but explicit is clearer.