Building Custom Reference Types in TypeScript
TypeScript's reference types allow you to define complex data structures that maintain state and are passed by reference. This challenge will guide you through creating and manipulating custom reference types, demonstrating how changes to one instance affect others that reference the same data. Understanding reference types is crucial for managing complex application state and avoiding unexpected behavior.
Problem Description
You are tasked with creating a ShoppingCart class in TypeScript that represents a shopping cart with a list of items. Each item in the cart should have a name (string) and a price (number). The ShoppingCart class should allow adding items, removing items, and calculating the total price of all items in the cart. Crucially, the items property should be a reference type (an array) so that modifications to the array within the ShoppingCart instance are reflected if the array is accessed elsewhere.
Key Requirements:
- Create a
ShoppingCartclass with a privateitemsproperty, which is an array of objects. Each object in the array should havenameandpriceproperties. - Implement an
addItemmethod that adds a new item to theitemsarray. - Implement a
removeItemmethod that removes an item from theitemsarray by its name. - Implement a
getTotalPricemethod that calculates and returns the sum of the prices of all items in the cart. - Ensure that the
itemsproperty is a reference type, meaning that changes to the array outside the class should be reflected within the class.
Expected Behavior:
- When a new
ShoppingCartis created, itsitemsarray should be empty. - Adding items to the cart should correctly populate the
itemsarray. - Removing an item by name should correctly remove it from the
itemsarray. getTotalPriceshould accurately calculate the sum of the prices of all items in the cart.- Modifying the
itemsarray directly (outside the class methods) should affect theShoppingCartinstance.
Edge Cases to Consider:
- What happens if you try to remove an item that doesn't exist in the cart? (The method should handle this gracefully, e.g., by doing nothing).
- What happens if the price of an item is negative or zero? (The
getTotalPricemethod should handle this correctly). - What happens if the cart is empty? (The
getTotalPricemethod should return 0).
Examples
Example 1:
Input:
const cart = new ShoppingCart();
cart.addItem({ name: "Apple", price: 1.0 });
cart.addItem({ name: "Banana", price: 0.5 });
Output:
cart.getTotalPrice() === 1.5
Explanation:
Two items are added to the cart, and the total price is correctly calculated.
Example 2:
Input:
const cart = new ShoppingCart();
cart.addItem({ name: "Apple", price: 1.0 });
cart.removeItem("Apple");
Output:
cart.getTotalPrice() === 0
Explanation:
An item is added, then removed, and the total price is correctly updated to 0.
Example 3:
Input:
const cart = new ShoppingCart();
const items = [{ name: "Orange", price: 0.75 }];
cart.items = items; // Directly modifying the items array
Output:
cart.getTotalPrice() === 0.75
Explanation:
The items array is directly modified outside the class, and the change is reflected in the cart's total price.
Constraints
- The
nameproperty of each item must be a string. - The
priceproperty of each item must be a number. - The
getTotalPricemethod must return a number. - The
itemsarray must be a reference type. - The code must be valid TypeScript.
Notes
- Pay close attention to the visibility modifiers (e.g.,
private) when defining theitemsproperty. - Consider using a type alias or interface to define the structure of an item in the cart.
- The key to this challenge is understanding how reference types work in TypeScript and how they affect the behavior of your code. Directly assigning a new array to
cart.itemswill demonstrate the reference behavior.