SOLUTION: Challenge 1 - Create a Barrel Export =============================================== Challenge: Create three utility modules (math.ts, string.ts, array.ts) with exported functions. Then create an index.ts barrel that re-exports all. Test importing from the barrel. --- SOLUTION: // src/utils/math.ts export function add(a: number, b: number): number { return a + b; } export function multiply(a: number, b: number): number { return a * b; } export function divide(a: number, b: number): number { if (b === 0) throw new Error("Division by zero"); return a / b; } --- // src/utils/string.ts export function capitalize(str: string): string { return str.charAt(0).toUpperCase() + str.slice(1); } export function trim(str: string): string { return str.trim(); } export function reverse(str: string): string { return str.split("").reverse().join(""); } --- // src/utils/array.ts export function flatten(arr: (T | T[])[]): T[] { return arr.reduce((acc, item) => { if (Array.isArray(item)) { acc.push(...item); } else { acc.push(item); } return acc; }, [] as T[]); } export function unique(arr: T[]): T[] { return [...new Set(arr)]; } export function chunk(arr: T[], size: number): T[][] { const result: T[][] = []; for (let i = 0; i < arr.length; i += size) { result.push(arr.slice(i, i + size)); } return result; } --- // src/utils/index.ts (BARREL EXPORT) export * from "./math"; export * from "./string"; export * from "./array"; --- // app.ts (USAGE) // Import everything from the barrel in one line import { add, multiply, capitalize, reverse, flatten, unique, chunk } from "./src/utils"; console.log(add(5, 3)); // 8 console.log(multiply(4, 7)); // 28 console.log(capitalize("hello")); // "Hello" console.log(reverse("world")); // "dlrow" console.log(flatten([1, [2, 3], 4])); // [1, 2, 3, 4] console.log(unique([1, 2, 2, 3, 3, 3])); // [1, 2, 3] console.log(chunk([1, 2, 3, 4, 5], 2)); // [[1, 2], [3, 4], [5]] --- EXPLANATION: BARREL EXPORT PATTERN: 1. Create separate modules for related functions (math.ts, string.ts, etc.) 2. Each module exports only its functions (no default export needed) 3. Create index.ts in the same directory 4. index.ts re-exports all using "export * from './submodule'" BENEFITS: 1. Cleaner API: Import once, get everything 2. Organized: Related functions grouped by file 3. Scalable: Add more submodules; barrel automatically includes them 4. Flexibility: Still import specific functions if you want WITHOUT BARREL: import { add, multiply } from "./src/utils/math"; import { capitalize, reverse } from "./src/utils/string"; import { flatten, unique } from "./src/utils/array"; WITH BARREL: import { add, multiply, capitalize, reverse, flatten, unique } from "./src/utils"; Much cleaner! --- ADVANCED: Selective Re-export You can selectively re-export if you want to hide some functions: // src/utils/index.ts (selective) export { add, multiply } from "./math"; // Only these math functions export * from "./string"; // All string functions // array.ts is NOT re-exported (private) This lets you control what's part of the public API. --- GOTCHA: Circular Dependencies If math.ts tries to import from string.ts and vice versa, you'll have a circular dependency. Avoid this by: 1. Not importing between utility modules 2. Moving shared types to a separate types.ts file 3. Using dependency injection instead of direct imports --- REAL-WORLD USAGE: This pattern is used everywhere: - React: import { useState, useEffect } from "react"; - lodash: import { map, filter } from "lodash"; - Material-UI: import { Button, Card } from "@mui/material"; All are barrel exports internally!