Featured resource
2025 Tech Upskilling Playbook
Tech Upskilling Playbook

Build future-ready tech teams and hit key business milestones with seven proven plays from industry leaders.

Check it out
  • Lab
    • Libraries: If you want this lab, consider one of these libraries.
    • Core Tech
Labs

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 platform
Lab Info
Level
Beginner
Last updated
Oct 10, 2025
Duration
45m

Contact sales

By clicking submit, you agree to our Privacy Policy and Terms of Use.
Table of Contents
  1. 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.

  2. 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.

  3. 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:

    1. Start the application by running npm run dev -- --host.
    2. Navigate to {{localhost:5173}} in a new tab.
    3. Open the Developer Tools (F12 or Control + Shift + I).
    4. Go to the Sources tab.
    5. In the filetree on the left, navigate to src/cart.ts.
    6. Find the calculateTotal function and click on the line number next to it to set a breakpoint.
    7. Add items to the cart to trigger the breakpoint.
    8. 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 the reduce function to get the right total.
  4. 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 an undefined 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:

    1. Reproduce the crash. The tests will do this for you, but you can also trigger it manually by calling the function from the console.
    2. 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.
    3. 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 in removeItemFromCart. The findIndex method returns -1 if the item isn't found. If you call cart.splice(-1, 1), it removes the last item from the array, which is not the desired behavior. Add a check to ensure you only call splice when itemIndex is a valid index (0 or greater).
  5. 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 the CartItem interface you just created. Your task is to change the type of the cart state from let cart: any[] = []; to use your new, strongly-typed CartItem[].

  6. 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 the totalPrice as a number. Move the logic for creating the summary <div> from renderCart into this new function. It should return the HTMLDivElement containing the formatted total price.

  7. 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 make renderCart 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 your createCartSummaryElement function. Append the element it returns to the cart container. With this change, the refactoring is complete!

  8. 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 custom interface, 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

Pluralsight Code Labs offer an opportunity to get hands-on learning in real-time. Be it a Challenge, Sandbox, or Guided Lab, these provide the real world experience needed to succeed in your development role.

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.

Get started with Pluralsight