TypeScript Tutorial
TypeScript Project: Bank System
An Account class with deposit, withdraw, and a printed statement. Balance never goes negative.
What you will build
A tiny bank is one object: an Account. The balance is private. Callers deposit, withdraw, and print a statement. They never assign the balance from outside the class. A withdrawal that would drop below zero is refused, and the old balance stays.
Demo amounts are literals at the bottom of the file, so the program does not wait on readLine(). Compile it with Try it in TypeScript at /typescript/try, not at the Python or C++ editors.
Private balance
Mark balance with private. Methods of Account can still read and write it. Code outside the class cannot. That is how the class enforces the no-negative rule in one place instead of hoping every caller remembers it.
Example
class Account {
private balance: number;
constructor(start: number) {
if (start < 0) {
this.balance = 0;
} else {
this.balance = start;
}
}
getBalance(): number {
return this.balance;
}
}
const a = new Account(50);
console.log(a.getBalance());Output is 50. A starting value below zero is stored as 0. There is still no deposit or withdraw. Those come next.
Deposit
Deposit adds a positive amount. Zero or a negative number is ignored so a caller cannot use deposit to shrink the balance. The method returns nothing; the next print shows the new total.
Example
class Account {
private balance: number;
constructor(start: number) {
this.balance = start < 0 ? 0 : start;
}
deposit(amount: number): void {
if (amount > 0) {
this.balance = this.balance + amount;
}
}
getBalance(): number {
return this.balance;
}
}
const a = new Account(50);
a.deposit(25);
a.deposit(-5);
console.log(a.getBalance());Output is 75. The negative deposit did not apply. Only 25 was added to 50.
Open this at /typescript/try with Try it in TypeScript. Change the starting balance to 0 and deposit 10 twice. You should see 20.
Withdraw without going negative
Withdraw succeeds only when the amount is positive and not larger than the current balance. Returntrue on success so the caller can print whether the cash left the account. On failure, leavethis.balance unchanged.
Example
class Account {
private balance: number;
constructor(start: number) {
this.balance = start < 0 ? 0 : start;
}
withdraw(amount: number): boolean {
if (amount <= 0) {
return false;
}
if (amount > this.balance) {
return false;
}
this.balance = this.balance - amount;
return true;
}
getBalance(): number {
return this.balance;
}
}
const a = new Account(50);
if (a.withdraw(20)) {
console.log("Withdrew 20");
} else {
console.log("Withdraw 20 failed");
}
if (a.withdraw(40)) {
console.log("Withdrew 40");
} else {
console.log("Withdraw 40 failed");
}
console.log("Balance " + a.getBalance());20 leaves the account. 40 would require 70 and the balance is then 30, so that call fails. The last line printsBalance 30.
Complete program with a statement
print is a method. It reads the private balance and writes a short statement.toFixed(2) shows two digits after the decimal so money reads as currency. The file runs a fixed sequence: open, deposit, two withdrawals, print.
Example
class Account {
private balance: number;
constructor(start: number) {
this.balance = start < 0 ? 0 : start;
}
deposit(amount: number): void {
if (amount > 0) {
this.balance = this.balance + amount;
}
}
withdraw(amount: number): boolean {
if (amount <= 0 || amount > this.balance) {
return false;
}
this.balance = this.balance - amount;
return true;
}
print(): void {
console.log("Statement");
console.log("Balance: $" + this.balance.toFixed(2));
}
}
const checking = new Account(100.00);
checking.deposit(40.00);
if (!checking.withdraw(25.50)) {
console.log("First withdraw refused");
}
if (!checking.withdraw(200.00)) {
console.log("Overdraft refused");
}
checking.print();Start at 100.00, add 40.00, take 25.50. The 200.00 withdrawal is refused. The statement showsBalance: $114.50. You cannot write checking.balance = -1 from outside the class; the field is private and tsc will reject it.
Common mistakes
- Leaving
balancepublic. Then any line can set it to a negative number and the class rules become decoration. - Subtracting first and checking the result afterward. If you write
this.balance = this.balance - amountbefore the test, a refused withdraw already damaged the value. - Treating a failed withdraw as success because you forgot to return
falseon theamount > this.balancepath. - Printing money without
toFixed(2).114.5looks like a truncated figure;114.50reads as currency.
Practice
- Change the starting balance from 100.00 to 20.00 and confirm the 25.50 withdraw is now refused.
- Add a second deposit of 10.00 after the first withdraw and print the new statement.
- Hold two
Accountobjects, transfer 15.00 from one to the other only when withdraw succeeds, then print both statements.
Next project: a scored quiz stored as an array of questions.