class Department {
name: string;
constructor(n: string) {
this.name = n;
}
}
const accounting = new Department('Accounting');
this
inside a class prevents an unexpected error.class Department {
name: string;
constructor(n: string) {
this.name = n;
}
describe(this: Department) { // (*) this always poining "Department"
console.log(this.name);
}
}
const accounting = new Department('Accounting');
accounting.describe(); // working
const accountingCopy = { describe: accounting.describe };
accountingCopy.describe(); // error
Access modifiers used to encapsulate certain components. (control accessibility from outside)
public / private / protected
readonly
Private vs Protected
Private
can only be accessible inside class not extended class but protected
can be accessible from extended class as well.
💫 Shorthand
class Department {
constructor(public readonly id: string, private name: string, private employees: string[]) {} // (*)
// ...
}
class Department {
readonly name: string; // (*) cannot modify
private employees: string[] = []; // (*) only accessible within class
constructor(n: string) {
this.name = n;
}
describe(this: Department) {
console.log(this.name);
}
addEmployee(employee: string) {
this.employees.push(employee)
}
printEmployeeInfo() {
console.log(employees.length);
console.log(employees);
}
}
const accounting = new Department('Accounting');
accounting.addEmployee('Suyeon');
accounting.printEmployeeInfo();
accounting.employees[1] = 'Hanna'; // error!
getter
: read-onlysetter
: set private field()
class Point {
constructor(private _x?: number, private _y?: number) { // (*) _x
}
get x() {
return this.x;
}
set x(value) {
if(value < 0) throw new Error('value cannot be less than 0.')
this.x = value;
}
draw() {
console.log(`x: ${this.x}, y: ${this.y}`);
}
}
let point = new Point(1, 2);
let x = point.x; // (*) get
point.x = 10; // (*) set
You can call method or property of class directly without creating an instance with
new
keyword.
this.fiscalYear
inside class but can access Department.fiscalYear
.class Department {
static fiscalYear = 2020; // (*)
constructor(private name: string) {
// console.log(this.fiscalYear); Not working
console.log(Department.fiscalYear);
}
static createEmployee(name: string) { // (*)
return { name: name };
}
}
const employee1 = Department.createEmployee('Suyeon'); // (**)
console.log(employee1, Department.fiscalYear);
Abstract classes are base classes from which other classes may be derived. if there are abstract method or property, its instances must have it. It is useful to force sharing the same method or propety but its implementation(detail) is up to derived classes.
// abstract class
abstract class Department {
constructor(public name: string) {}
abstract printMeeting(): void; // (*)
}
// sub class
class AccountingDepartment extends Department {
constructor() {
super("Accounting and Auditing");
}
generateReports(): void {
console.log("Generating accounting reports..."); // (**)
}
}
Singleton is a creational design pattern, which ensures that only one object of its kind exists and provides a single point of access to it for any other code.
- State Management
class Singleton {
private static instance: Singleton;
private constructor() {
// do something construct...
}
static getInstance() {
if (!Singleton.instance) {
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
someMethod() { }
}
let something = new Singleton(); // Error: constructor of 'Singleton' is private.
let instance = Singleton.getInstance(); // do something with the instance...