/
Customer.ts
120 lines (105 loc) · 3.37 KB
/
Customer.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/**
* An abstract base class for the customer entity in our application.
*
* Notice how TypeDoc shows the inheritance hierarchy for our class.
*
* @category Model
*/
export abstract class Customer {
/** A public readonly property. */
readonly id: number;
/** A public property that can be reassigned. */
name: string;
/** An optional protected property. */
protected contactName?: string;
/** A private property that is accessed via a getter and setter. */
private _nextOrderNumber = 0;
/**
* A getter that prepends a number sign to the private `_nextOrderNumber`
* property.
*/
get nextOrderNumber(): string {
return `#${this._nextOrderNumber}`;
}
/**
* A setter that takes in either a string or a number and sets the private
* `_nextOrderNumber` property.
*/
set nextOrderNumber(value: string | number) {
if (typeof value === "number") {
this._nextOrderNumber = value;
} else {
this._nextOrderNumber = parseInt(value.replace(/#/g, ""));
}
}
/**
* The constructor of the `Customer` class.
*
* @param id the customer's database ID
* @param name the customer's name
* @param nextOrderNumber the next number to use when this customer places an order
*/
constructor(id: number, name: string, nextOrderNumber: string | number) {
this.id = id;
this.name = name;
this.nextOrderNumber = nextOrderNumber;
this.doInternalStuff();
}
/** A public method. To be called when an order is placed for this customer. */
onOrderPlaced(): void {
this._nextOrderNumber++;
}
/**
* A public method that's defined using an arrow function.
*
* TypeDoc knows to document this as a method rather than a property.
*/
onOrderPlacedArrowFunction = (): void => {
this._nextOrderNumber++;
};
/** A protected method. */
protected isValid(): boolean {
return this._nextOrderNumber >= 0;
}
/** A private method. */
private doInternalStuff(): void {
// does nothing
}
}
/**
* A class that extends [[`Customer`]].
*/
export class DeliveryCustomer extends Customer {
/** A property defined on the subclass. */
preferredCourierId?: number;
/** Another property defined on the subclass. */
readonly subscriptionType: "basic" | "enterprise";
/**
* The constructor of the `DeliveryCustomer` class.
*
* @param id the customer's database ID
* @param name the customer's name
* @param nextOrderNumber the next number to use when this customer places an order
* @param subscriptionType whether this customer has a basic or enterprise subscription
*/
constructor(
id: number,
name: string,
nextOrderNumber: string | number,
subscriptionType: "basic" | "enterprise"
) {
super(id, name, nextOrderNumber);
this.subscriptionType = subscriptionType;
}
/**
* An example of overriding a protected method.
*
* A `DeliveryCustomer` can only have a preferred courier if its
* subscription type is enterprise.
*/
protected isValid(): boolean {
if (!super.isValid()) return false;
if (this.subscriptionType === "enterprise") return true;
return typeof this.preferredCourierId === "undefined";
}
}