
최근에 타입스크립트를 조금 더 깊이 있게 파고들고 있는데, 이번엔 '클래스'를 정리해보려고 한다. 자바스크립트에도 클래스가 있지만, 타입스크립트에서는 타입 시스템과 함께 클래스가 훨씬 더 구조적으로 다뤄진다. 특히 접근 제어자나 인터페이스와의 결합이 굉장히 매력적이다.
자바스크립트의 클래스 문법을 확장한 형태다. 중요한 차이점은 클래스 필드에 타입을 명시적으로 지정할 수 있다는 것이다. 타입을 지정하지 않으면 매개변수와 마찬가지로 암시적으로 any로 추론되는데, strict 모드에선 에러가 발생할 수 있다.
class Employee {
name: string = "";
age: number = 0;
position: string = "";
work() {
console.log("일함");
}
}
생성자에서 필드를 잘 초기화해주면 클래스 선언 시 초기값은 생략 가능하다.
class Employee {
name: string;
age: number;
position: string;
constructor(name: string, age: number, position: string) {
this.name = name;
this.age = age;
this.position = position;
}
work() {
console.log("일함");
}
}
class Employee {
name: string;
age: number;
position?: string;
constructor(name: string, age: number, position?: string) {
this.name = name;
this.age = age;
this.position = position;
}
}
타입스크립트에서는 클래스 자체가 타입으로도 사용된다.
const employee: Employee = {
name: "",
age: 0,
position: "",
work() {},
};
class ExecutiveOfficer extends Employee {
officeNumber: number;
constructor(name: string, age: number, position: string, officeNumber: number) {
super(name, age, position);
this.officeNumber = officeNumber;
}
}
파생 클래스에서 생성자를 정의하면 반드시 super()를 호출해야 하며, 생성자의 최상단에서 호출해야 한다.
타입스크립트는 다음과 같은 접근 제어자를 제공한다.
public: 어디서든 접근 가능 (기본값)private: 클래스 내부에서만 접근 가능protected : 클래스 내부 + 파생 클래스에서만 접근 가능class Employee {
private name: string;
protected age: number;
public position: string;
constructor(name: string, age: number, position: string) {
this.name = name;
this.age = age;
this.position = position;
}
work() {
console.log(`${this.name}이 일함`);
}
}
class ExecutiveOfficer extends Employee {
showAge() {
console.log(this.age); // 가능
}
}
const emp = new Employee("Lee", 30, "Developer");
emp.name; // ❌
emp.age; // ❌
emp.position; // ✅
생성자의 매개변수에 접근 제어자를 붙이면 필드 선언과 this 할당을 생략할 수 있다.
class Employee {
constructor(
private name: string,
protected age: number,
public position: string
) {}
work() {
console.log(`${this.name} 일함`);
}
}
이게 훨씬 깔끔하다.
타입스크립트의 인터페이스는 클래스가 반드시 따라야 하는 설계도 역할을 한다.
interface CharacterInterface {
name: string;
moveSpeed: number;
move(): void;
}
class Character implements CharacterInterface {
constructor(
public name: string,
public moveSpeed: number,
private extra: string
) {}
move() {
console.log(`${this.moveSpeed} 속도로 이동!`);
}
}
인터페이스를 통해 클래스의 구조를 강제할 수 있어서 협업이나 코드 관리에 유용하다.
이런 구조 덕분에 타입스크립트의 클래스는 훨씬 더 견고하고 유지보수하기 좋은 구조로 코드를 작성할 수 있게 해준다. 다음엔 abstract class, readonly, static 키워드도 정리해봐야겠다.