Challenge 3: Type and Implement a Polyfill — Possible Solution ==================================================================== // Step 1: the type declaration — tells the compiler this method exists export {}; // makes this file a module, so `declare global` is valid here declare global { interface Array { last(): T | undefined; } } // Step 2: the actual runtime implementation — this is what makes it real if (!Array.prototype.last) { Array.prototype.last = function (this: T[]): T | undefined { return this.length > 0 ? this[this.length - 1] : undefined; }; } // --- Usage --- const numbers = [10, 20, 30]; console.log(numbers.last()); // 30 — typed as number | undefined const empty: string[] = []; console.log(empty.last()); // undefined — typed as string | undefined, matching reality // Proof the declaration alone would NOT be enough: // If Step 2 were skipped entirely, `numbers.last()` would still compile // cleanly (the type declaration satisfies the compiler) but would throw // "numbers.last is not a function" at runtime — exactly the gotcha this // chapter warns about. WHY THIS WORKS -------------- - `declare global { interface Array { last(): T | undefined } }` merges into TypeScript's built-in Array interface (the same declaration merging mechanic as Challenge 1, applied to a global, built-in type rather than one of your own), making `.last()` type-check on any array anywhere in the codebase. - The `if (!Array.prototype.last)` guard is standard polyfill hygiene: it avoids overwriting a native implementation if the running JavaScript engine already provides one, and avoids re-assigning it if this module is loaded more than once. - Returning `T | undefined` (not just `T`) is honest about what happens on an empty array — `this[this.length - 1]` on an empty array is `undefined` at runtime, so the type accurately reflects that possibility instead of promising a value that might not exist.