TypeScript and Object-Oriented Programming
Scenario
You are working as a software developer for a company that manages a large inventory of products. The inventory system must account for both physical items, like electronics and apparel, and digital products, such as e-books and software licenses. Due to the complexity of managing different product types, your team is shifting toward an object-oriented design that will simplify the codebase and make it easier to extend in the future.
Your supervisor has tasked you with building a prototype for an inventory tracker. This prototype should distinguish between physical and digital products, handle tax calculations based on product type, and manage the inventory in a structured way. You will leverage TypeScript and object-oriented programming to create reusable, scalable code and meet the team’s standards for type safety and maintainability.
To further improve this system, you will also develop a modular structure that separates concerns, making it easier to maintain and add features down the line. Once completed, this prototype will form the basis of the company’s inventory management application.
Task
Create a simple object-oriented inventory tracker using TypeScript. The tracker will distinguish between PhysicalProduct and DigitalProduct, calculate applicable taxes, and manage inventory using modules. This lab will reinforce the key object-oriented programming concepts learned in the last lesson, including inheritance, encapsulation, abstraction, and polymorphism, while using TypeScript features such as type annotations and interfaces.
Objective
By the end of this lab, you will demonstrate the ability to use TypeScript with type annotations, interfaces, and object-oriented programming concepts to build a small yet functional object-oriented system.
Instructions
-
Setup Your Project:
-
Create a new directory for the project and initialize it with npm:
mkdir inventory-tracker cd inventory-tracker npm init -y
-
Install TypeScript and other dependencies:
npm install typescript @types/node --save-dev
-
Create a
tsconfig.json
file:npx tsc --init
-
Set up a basic folder structure for the project:
inventory-tracker/ ├── src/ │ ├── models/ │ │ ├── Product.ts │ │ ├── PhysicalProduct.ts │ │ └── DigitalProduct.ts │ ├── utils/ │ │ └── taxCalculator.ts │ └── main.ts └── tsconfig.json
-
-
Create the Product Base Class:
- Inside
src/models/Product.ts
, create aProduct
base class with the following:- Properties:
sku
(string),name
(string),price
(number). - Methods:
displayDetails()
- a method that returns a formatted string with the product’s details.getPriceWithTax()
- a method that calculates the final price of the product with tax.
- Properties:
- Inside
-
Create the PhysicalProduct Subclass:
- Inside
src/models/PhysicalProduct.ts
, create aPhysicalProduct
class that extendsProduct
.- Add a
weight
property (number) for physical products. - Override the
getPriceWithTax()
method to calculate a final price that includes a 10% tax rate. - Use a getter method to return the formatted weight in kilograms (e.g. “2.5 kg”).
- Add a
- Inside
-
Create the DigitalProduct Subclass:
- Inside
src/models/DigitalProduct.ts
, create aDigitalProduct
class that extendsProduct
.- Add a
fileSize
property (number) for digital products. - Override the
getPriceWithTax()
method to calculate a final price with no tax, since the digital products do not require tax. - Use a getter method to return the formatted file size in megabytes.
- Add a
- Inside
-
Create a Tax Calculator Utility:
- Inside
src/utils/taxCalculator.ts
, create a utility module to handle tax calculations.- Add a function
calculateTax()
that accepts aProduct
object and returns the price including tax.
- Add a function
- Inside
-
Implement the Main Program:
- Inside
src/main.ts
, import thePhysicalProduct
andDigitalProduct
classes, and create instances of both. - Use a loop to display the details of each product, calculate prices with tax, and display the final prices.
- Hint: Utilize polymorphism to your advantage here.
- Inside
-
Compile and Run the Program:
-
Compile the TypeScript code:
npx tsc
-
Run the compiled JavaScript:
node dist/main.js
-
Challenge
- Add a
DiscountableProduct
interface that includes a methodapplyDiscount()
. Implement this interface in one of the product classes. - Implement a module to handle sorting products by price or by name.
- Add a new feature to the inventory system: bulk discounts for physical products over a certain quantity or size.
Critical Thinking
After completing the lab, consider the following questions:
- How does TypeScript enforce type safety in this object-oriented program?
- How did inheritance reduce code duplication for
PhysicalProduct
andDigitalProduct
? - What are the benefits of using encapsulation and access modifiers (
public
,private
,protected
) in this context? - If you had to add a new type of product (e.g., a
SubscriptionProduct
), how would polymorphism make this extension straightforward?
By completing this lab, you will demonstrate your understanding of TypeScript, type annotations, interfaces, and key object-oriented programming concepts such as inheritance, encapsulation, and polymorphism.