- Lab
-
Libraries: If you want this lab, consider one of these libraries.
- Core Tech

Guided: Debug and Refactor TypeScript Code Using Source Maps
In this Code Lab, you'll debug and refactor a buggy TypeScript shopping cart application. You will use browser developer tools and source maps to find and fix errors, then improve the code's structure and type safety for better maintainability.

Lab Info
Table of Contents
-
Challenge
Step 1: Introduction
Welcome to the Guided Code Lab on Debugging and Refactoring TypeScript! In this lab, you'll work with a simple, but buggy, shopping cart application. Your mission is to use modern developer tools to hunt down and fix issues, then refactor the code to make it more professional and maintainable.
You'll start by learning how to use source maps, a powerful tool that lets you debug your original TypeScript code directly in the browser, even though it's been compiled into JavaScript. Then, you'll put your detective skills to the test to solve a logic error and a runtime crash. Finally, you'll apply best practices like using interfaces and breaking down large functions to improve the overall code quality.
It's time to get started!
This lab experience was developed by the Pluralsight team using Forge an internally developed AI tool utilizing Gemini technology. All sections were verified by human experts for accuracy prior to publication. For issue reporting, please contact us.
-
Challenge
Step 2: Enabling Source Maps
Before you can debug effectively, you need to bridge the gap between the TypeScript code you write and the JavaScript code the browser runs. This is where source maps come in. A source map is a file that maps from the compiled code back to the original source code, allowing debuggers to display your
.ts
files instead of the generated.js
files.To enable them, you need to configure both the TypeScript compiler and your development server (Vite). Next, you need to tell the Vite development server to serve these source maps to the browser. Open
vite.config.ts
. You will add a new property to the configuration to enable source maps for the server. -
Challenge
Step 3: Debugging a Logic Error
Now that source maps are enabled, you'll hunt down your first bug. If you add two "Premium Widgets" to the cart, the total price is calculated incorrectly. The discount logic is flawed.
This is a classic logic error. The code runs without crashing, but it produces the wrong result. Your goal is to use the browser's debugger to step through the calculation and find the mistake.
How to Debug:
- Start the application by running
npm run dev -- --host
. - Navigate to {{localhost:5173}} in a new tab.
- Open the Developer Tools (
F12
orControl + Shift + I
). - Go to the Sources tab.
- In the filetree on the left, navigate to
src/cart.ts
. - Find the
calculateTotal
function and click on the line number next to it to set a breakpoint. - Add items to the cart to trigger the breakpoint.
- Use the debugger controls (Step Over, Step Into) and the Scope or Watch panels to inspect variable values as the code executes. You've fixed the discount, but the total is still wrong! Stepping through the
calculateTotal
function again reveals another problem: the discount is subtracted before the price is multiplied by the quantity. This is an order of operations issue. Correct the formula in thereduce
function to get the right total.
- Start the application by running
-
Challenge
Step 4: Fixing a Runtime Error
Your next bug is more dramatic: a runtime error. If you try to update the quantity of a non-existent item (which can happen in more complex apps), the application crashes with a
TypeError
. This happens because the code tries to access a property on anundefined
value.Your task is to make the code more robust by adding guard clauses—checks that prevent the faulty code from running.
How to Debug:
- Reproduce the crash. The tests will do this for you, but you can also trigger it manually by calling the function from the console.
- Look at the error message in the console. It will include a call stack, which shows the chain of function calls that led to the error.
- Click on the link in the call stack that points to
cart.ts
to jump directly to the line of code that caused the error. A similar, more subtle bug exists inremoveItemFromCart
. ThefindIndex
method returns-1
if the item isn't found. If you callcart.splice(-1, 1)
, it removes the last item from the array, which is not the desired behavior. Add a check to ensure you only callsplice
whenitemIndex
is a valid index (0 or greater).
-
Challenge
Step 5: Improving Type Safety
With the bugs fixed, you can focus on improving the code's quality. One of the biggest advantages of TypeScript is type safety, but your code isn't using it effectively. The cart is currently an array of
any
(any[]
), which means you lose all of TypeScript's help and risk introducing new bugs.You'll fix this by creating a specific interface to define the shape of a cart item. Now, open
src/cart.ts
. Import theCartItem
interface you just created. Your task is to change the type of thecart
state fromlet cart: any[] = [];
to use your new, strongly-typedCartItem[]
. -
Challenge
Step 6: Refactoring Rendering Logic
The
renderCart
function is doing too much work. It's responsible for clearing the list, iterating through items, creating DOM elements for each item, attaching event listeners, and rendering the total. This violates the Single Responsibility Principle and makes the function hard to read and maintain.You will refactor this by breaking it down into smaller, specialized "factory" functions. Similarly, create and export another function named
createCartSummaryElement
. This function should take thetotalPrice
as a number. Move the logic for creating the summary<div>
fromrenderCart
into this new function. It should return theHTMLDivElement
containing the formatted total price. -
Challenge
Step 7: Finalizing the Refactor
You've created your new helper functions, but you're not using them yet. The final step is to update the main
renderCart
function to delegate the work to these new, smaller functions. This will makerenderCart
a simple "orchestrator" whose only job is to coordinate the rendering process. Finally, replace the block of code that creates the total price summary element with a call to yourcreateCartSummaryElement
function. Append the element it returns to the cart container. With this change, the refactoring is complete! -
Challenge
Step 8: Conclusion
Congratulations on completing the lab!
You've successfully taken a buggy, difficult-to-maintain application and transformed it into a robust and clean codebase.
Here's a recap of the professional skills you've practiced:
- Debugging with Source Maps: You configured your environment to debug original TypeScript code in the browser.
- Systematic Debugging: You used breakpoints, the call stack, and variable inspection to diagnose and fix both logic and runtime errors.
- Improving Type Safety: You replaced
any
with a custominterface
, leveraging TypeScript's compiler to prevent future bugs. - Refactoring for Maintainability: You applied the Single Responsibility Principle to break down a large function into smaller, reusable, and testable units.
These are essential skills for any modern web developer. Keep practicing them to write better, more reliable code!
About the author
Real skill practice before real-world application
Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.
Learn by doing
Engage hands-on with the tools and technologies you’re learning. You pick the skill, we provide the credentials and environment.
Follow your guide
All labs have detailed instructions and objectives, guiding you through the learning process and ensuring you understand every step.
Turn time into mastery
On average, you retain 75% more of your learning if you take time to practice. Hands-on labs set you up for success to make those skills stick.