(Typescript) 타입 선언 방법 3탄, 클래스 타입 선언 방법
이전 포스팅으로 객체와 변수, 함수 등의 타입 선언 방법에 대해 다루었다.
이번 포스팅에서는 클래스의 타입을 선언하는 방법에 대해서 정리하고자 한다.
타입스크립트의 클래스 선언 방법은 자바스크립트와 유사하지만,
접근 제어자, getter/setter, 인터페이스, abstract 클래스 등 타입스크립트만의 고유 기능이 있으며
이 기능들을 활용하면 좀 더 명확하고 안정성이 높은 코드를 짤 수 있다.
1. 클래스의 타입 선언 방법 / constructor 단축구문
클래스의 타입을 설정하는 타입스크립트의 기본 문법은 아래와 같다.
자바스크립트의 클래스 선언과 동일하게 필드 선언과 초기화(constructor)가 들어가 있고, 여기에 타입이 추가된다.
class User {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
}
이때 constructor 단축구문을 활용하면 필드 선언과 초기화를 한 번에 할 수 있다.
class User {
constructor(
public name: string,
public age: number
) {}
}
2. 제어자 (public, protected, private, readonly)
자바스크립트와 달리 타입스크립트에는 제어자가 존재한다.
제어자는 클래스 필드에 대한 접근을 제어할 수 있다.
- public: 기본 접근 제어자, 어디에서든 접근 가능
- private: 클래스 내부 및 서브클래스에서만 접근 가능
- protected: 클래스 내부 및 해당 클래스의 인스턴스에서만 접근 가능
- readonly: 읽기 전용 속성으로, 클래스 내부에서만 수정할 수 있음
class Animal {
constructor(
public name: string,
private type: string,
protected age: number,
readonly species: string
) {}
}
class Dog extends Animal {
constructor(name: string, age: number) {
super(name, 'Dog', age, 'Canine'); //부모 클래스로부터 상속
}
getDogAge(): number {
return this.age;
}
}
const dog = new Dog('Buddy', 5);
console.log(dog.name); // public 속성이라 자유롭게 접근 가능
console.log(dog.getDogAge()); // private 속성이라 get 메서드로 접근
// console.log(dog.type); // 에러 발생:private 속성
// dog.species = 'Feline'; // 에러 발생:readonly 속성
3. getter & setter
자바스크립트와 동일하게 getter와 setter을 활용해 private 필드에 안전하게 접근할 수 있다.
class User {
constructor(
public name: string,
private _age: number
) {}
get age(): number{
return this._age;
}
set age(newAge: number){
if(newAge<0){
throw new Error("Age cannot be negative!");
}
this._age = newAge;
}
}
const lily = new User("lily", 20);
lily.age //get 20
lily.age = 50 //set 50
4. 인터페이스를 활용한 선언
인터페이스를 활용해 클래스를 선언할 수도 있다.
특정 인터페이스로 클래스를 구현하려면, implement 키워드를 사용하면 된다.
interface Name{
name: string;
sayHi(): void;
}
class User implements Name{
constructor(
public name: string,
private _age: number
) {}
sayHi(): void {
console.log(`Hi, my name is ${this.name}`);
}
}
const lily = new User("lily", 20);
lily.sayHi(); //Hi, my name is lily
5. abstract 클래스
abstract 키워드를 붙인 추상 클래스는 자신의 인스턴스를 생성할 수 없다.
추상 클래스는 다른 클래스가 반드시 구현해야 하는 메서드를 정의할 수 있다.
이런 점에서 추상 클래스는 인터페이스와 유사하지만 차이점이 있다.
추상 클래스는 인터페이스와 달리 구현을 가질 수 있으며, 스태틱 메서드와 속성도 가질 수 있다.
이로 인해 추상 클래스는 인터페이스보다 더 유연한 구조를 제공한다.
- 추상 메서드 (abstract)
- abstract 키워드를 사용
- 구현이 없어야 함
- 서브클래스에서 반드시 구현해야 함
- 일반 메서드
- 구현을 가짐
- 서브 클래스에서 재정의(오버라이드) 가능
- 인스턴스에 속하며, 인스턴스를 통해 호출
- this 키워드로 인스턴스 속성에 접근 가능
- 정적 메서드 (static)
- static 키워드를 사용
- 클래스 자체에 속하며, 클래스를 통해 호출
- this 키워드로 해당 클래스의 정적 속성에 접근 가능
- 인스턴스에 접근 불가
abstract class Name {
constructor(public name: string, public age: number) {}
// 추상 메서드: 서브클래스에서 반드시 구현해야 함
abstract sayHi(): void;
// 스태틱 메서드
static saySpecies(): void {
console.log("I'm human");
}
// 일반 메서드
sayAge(): void {
console.log(`I am ${this.age} years old.`);
}
}
class User extends Name {
constructor(name: string, age: number) {
super(name, age);
}
// 추상 메서드 구현
sayHi(): void {
console.log(`Hi, my name is ${this.name}.`);
}
}
const user = new User('Alice', 30);
user.sayHi(); // "Hi, my name is Alice." //추상 메서드
user.sayAge(); // "I am 30 years old." //일반 메서드
Name.saySpecies(); // "I'm human" //스태틱 메서드