Tracking Expenses by Month and Users
TrackedMonth Class#
Our app begins to take shape when we place Budget
in the context of time. Conceptually, a budget can belong to any span of time such as a a monthly, daily, or yearly budget. The time span that makes the most sense for our FinanceMe
is monthly, so we are creating a TrackedMonth
class that holds a month's worth of budgets.
Below is the class diagram for our class:

The month
argument passed to the constructor is of type Month
while the year
argument is type number
. Months have their own type because they represent a finite set of numbers (one through twelve), so we can use a more specific type to ensure only valid months are used.
We can statically enforce that only valid months are passed to our constructor by using type aliases and the union operator that we learned in the previous section.
Type aliases use the type
keyword to assign a name to the result of a type expression. Below are a few examples of valid type aliases:
type Age = number;
type Identifier = string;
type Week = 1 | 2 | 3 | 4 | 5 | 6 | 7;
const age: Age = 30;
const id: Identifier = '1udua';
const day: Week = 2;
Type aliases can be exported and imported like any other identifier in TypeScript. We create a Month
type alias and save it in a shared types
directory at the top level so that it can be reused by various entities:
type Month =
| 1
| 2
| 3
| 4
| 5
| 6
| 7
| 8
| 9
| 10
| 11
| 12;
export default Month;
We now import and use our Month
type in the TrackedMonthly
class along with the year
and budgets
properties:
import Month from '../types/Month';
import Budget from './Budget';
class TrackedMonth {
private month: Month;
private year: number;
private budgets: Budget[];
constructor(
month: Month,
year: number,
budgets: Budget[],
) {
this.updateMonth(month);
this.updateYear(year);
this.budgets = budgets;
}
getMonth(): Month {
return this.month;
}
updateMonth(month: Month) {
this.month = month;
}
getYear(): number {
return this.year;
}
updateYear(year: number) {
this.year = year;
}
getBudgets(): Budget[] {
return this.budgets;
}
}
export default TrackedMonth;
User Class#
The User
class is the final abstraction we need to build a meaningful program. It holds an array of TrackedMonth
objects that represent the months that the user logged budgets and expenses for. Because each month has its own collection of budgets, the user can retroactively modify budgets without affecting the budgets for other months. The user can also create and remove budgets on a monthly basis.
Below is the class diagram for User
:

Most of the exposed methods are simple setters/getters similar to those we've seen before, so our initial implementation defines our class and the associated setters/getters:
import TrackedMonth from './TrackedMonth';
import genUniqueId from '../utils/genUniqueId';
import Month from '../types/Month';
This page is a preview of Beginners Guide to TypeScript