Challenge 3: Version a Type — Possible Solution ==================================================================== interface ProductV1 { version: 1; id: string; title: string; // v1 called it "title" priceInCents: number; } interface ProductV2 { version: 2; id: string; name: string; // v2 renamed "title" to "name" price: number; // v2 uses dollars (number), not cents currency: string; // v2 added a currency field } type VersionedProduct = ProductV1 | ProductV2; // A normalized shape the rest of the app can use regardless of which // version the data came from. interface NormalizedProduct { id: string; name: string; price: number; // always in dollars currency: string; } function normalizeProduct(product: VersionedProduct): NormalizedProduct { if (product.version === 1) { // Narrowed to ProductV1 here — title/priceInCents exist, name/price/currency don't. return { id: product.id, name: product.title, price: product.priceInCents / 100, currency: "USD", // v1 never stored a currency — assume USD }; } // Narrowed to ProductV2 here. return { id: product.id, name: product.name, price: product.price, currency: product.currency, }; } // --- Usage --- const oldProduct: ProductV1 = { version: 1, id: "p1", title: "Widget", priceInCents: 999 }; const newProduct: ProductV2 = { version: 2, id: "p2", name: "Gadget", price: 19.99, currency: "EUR" }; console.log(normalizeProduct(oldProduct)); // { id: 'p1', name: 'Widget', price: 9.99, currency: 'USD' } console.log(normalizeProduct(newProduct)); // { id: 'p2', name: 'Gadget', price: 19.99, currency: 'EUR' } WHY THIS WORKS -------------- - `version` is a literal-typed discriminant (1 vs 2), so checking `product.version === 1` narrows the whole union the same way `status` did in Challenge 1's ApiResponse. - Each version keeps its own honest shape — ProductV1 never pretends to have a `currency` field it never actually stored — instead of one type bloated with optional fields for every version that ever existed. - normalizeProduct() is the single place that understands both versions, so the rest of the codebase only ever deals with NormalizedProduct.