TypeScript Tutorial
TypeScript Project: Shopping Cart
A cart of line items with name, quantity, and price. Print a receipt and the grand total.
What you will build
A cart is an array of line items. Each line has a name, a quantity, and a unit price. The receipt prints every line with an extended price (quantity times unit price) and a grand total. Money uses two decimal places throughtoFixed(2).
Items are hardcoded so the receipt is stable. Click Try it in TypeScript and run it at/typescript/try. Do not use the Python editor or the C++ compiler for this program.
A line item interface
Name is a string. Quantity is a number. Price is a number for the unit cost. The extended total is not stored; you compute it when you print so quantity changes cannot leave a stale field behind.
Example
interface Line {
name: string;
qty: number;
price: number;
}
function extended(item: Line): number {
return item.qty * item.price;
}
const tea: Line = {
name: "Green tea",
qty: 2,
price: 3.50,
};
console.log(tea.name + " x" + tea.qty + " = " + extended(tea));Two teas at 3.50 is 7. Default printing may show 7 rather than 7.00. Formatting comes next.
Two decimal places
Currency needs toFixed(2). Combine it with padStart so money columns line up. Pad the formatted string, not the raw number.
Example
function money(n: number): string {
return n.toFixed(2).padStart(8);
}
console.log(money(3.5));
console.log(money(7.0));
console.log(money(12.45));Open /typescript/try with Try it in TypeScript. You should see3.50, 7.00, and 12.45, each in an 8-character field.
An array of lines
Push each item onto the cart. A loop prints names. The grand total is the sum of extended for every row. Pass the cart into the receipt function.
Example
interface Line {
name: string;
qty: number;
price: number;
}
function extended(item: Line): number {
return item.qty * item.price;
}
const cart: Line[] = [];
cart.push({ name: "Green tea", qty: 2, price: 3.50 });
cart.push({ name: "Oat bun", qty: 1, price: 2.25 });
cart.push({ name: "Soup", qty: 3, price: 4.00 });
let total = 0;
for (const item of cart) {
total = total + extended(item);
console.log(item.name);
}
console.log("lines " + cart.length);
console.log("raw total " + total);Complete receipt
Print a header, one row per item with quantity, unit price, and line total, then a grand total. Skip items whose quantity is not positive so a zero-qty leftover does not show as a free product. This cart has three real lines.
Example
interface Line {
name: string;
qty: number;
price: number;
}
function extended(item: Line): number {
return item.qty * item.price;
}
function money(n: number): string {
return n.toFixed(2).padStart(10);
}
function printReceipt(cart: Line[]): void {
console.log(
"Item".padEnd(14) +
"Qty".padStart(5) +
"Price".padStart(10) +
"Total".padStart(10)
);
let grand = 0;
for (const item of cart) {
if (item.qty <= 0) {
continue;
}
const lineTotal = extended(item);
grand = grand + lineTotal;
console.log(
item.name.padEnd(14) +
String(item.qty).padStart(5) +
money(item.price) +
money(lineTotal)
);
}
console.log("Grand total".padEnd(14) + "".padStart(5) + "".padStart(10) + money(grand));
}
const cart: Line[] = [];
cart.push({ name: "Green tea", qty: 2, price: 3.50 });
cart.push({ name: "Oat bun", qty: 1, price: 2.25 });
cart.push({ name: "Soup", qty: 3, price: 4.00 });
printReceipt(cart);Line totals are 7.00, 2.25, and 12.00. The grand total is 21.25. Change soup to quantity 0 and that row disappears; the total drops to 9.25.
Common mistakes
- Storing money as an integer without a plan. This tutorial uses
numberand two displayed digits. For a later version you can store cents as integers; do not mix both in one receipt. - Printing the unit price as the line total. Multiply by quantity every time.
- Calling
padStarton the raw number. Format withtoFixed(2)first. - Left-aligning numbers and right-aligning names. Names read well on the left; money lines up on the right.
Practice
- Change green tea from quantity 2 to quantity 3 and confirm the grand total becomes 24.75.
- Add a fourth item and confirm the grand total includes it.
- Print a tax line of 8 percent of the grand total, then a new amount due. If the cart is empty, print
Cart is empty.
That is the last TypeScript project on this hub. Return to TypeScript Projectsor open /typescript/try and change the demo data on any program you already compiled.