숏컷 코드
class User {
constructor(
public id: string,
public name: string,
) {}
greet() {
return `Hello, ${this.name}`;
}
}클래스 형태
클래스에서 먼저 눈에 들어와야 하는 대표 형태는 아래입니다.
- 필드와 메서드가 있는 기본 클래스
- 생성자로 상태를 주입하는 클래스
- 접근 제한자와 매개변수 프로퍼티
extends/implements로 계약을 잇는 클래스
1) 클래스는 런타임 값과 타입 계약을 함께 만든다
TypeScript의 클래스는 JavaScript처럼 실제 생성자 함수 역할을 하면서, 동시에 인스턴스 구조의 타입 정보도 제공합니다.
class User {
constructor(public id: string) {}
}
const user = new User("u1");즉 클래스는 값 생성과 정적 계약이 만나는 지점입니다.
2) 접근 제한자는 상태 공개 범위를 정한다
public, private, protected는 클래스 내부 상태를 어디까지 열지 결정합니다.
class Counter {
constructor(private value = 0) {}
inc() {
this.value += 1;
}
}이 도구들은 런타임 보안보다 설계 의도를 더 명확히 보여 주는 역할에 가깝습니다.
3) 매개변수 프로퍼티는 생성자와 필드 선언을 묶는다
생성자 인자 앞에 접근 제한자를 붙이면 프로퍼티 선언과 초기화를 한 번에 표현할 수 있습니다. 간단한 모델에서는 코드 양을 줄이고 읽기 속도를 높여 줍니다.
class User {
constructor(
public id: string,
private token: string,
) {}
}4) 상속과 구현은 재사용과 계약을 분리해 보여 준다
클래스가 다른 클래스를 잇거나 인터페이스를 구현하면 구조 재사용과 공개 계약이 같이 드러납니다.
interface Greeter {
greet(): string;
}
class AdminUser extends User implements Greeter {
greet() {
return `Hello, ${this.id}`;
}
}그래서 extends와 implements는 문법보다 "무엇을 재사용하고 무엇을 약속하는가"를 읽는 표지로 보는 편이 좋습니다.
5) 단순 데이터 모델이면 클래스가 과할 수 있다
메서드나 생성 규칙 없이 값 구조만 필요한 경우에는 interface와 객체 리터럴 조합이 더 가볍습니다.
interface User {
id: string;
name: string;
}즉 클래스를 기본값으로 두기보다, 정말 상태와 행위가 같이 움직이는지 먼저 보는 편이 좋습니다.
6) 클래스는 객체지향 문법이 아니라 모델링 도구다
TypeScript에서 클래스는 객체지향 스타일을 강요하는 기능이 아니라, 특정 문제를 그렇게 모델링할 때 선택하는 도구입니다. 그래서 함수와 객체 리터럴, interface와 항상 비교하는 습관이 중요합니다.
언제 클래스를 쓸까
- 상태 + 메서드 + 생성 규칙이 함께 있다: 클래스
- 단순 구조 데이터만 필요하다: interface/객체 리터럴
- 외부 접근 범위를 제어한다: 접근 제한자
- 생성자에서 프로퍼티를 바로 선언한다: 매개변수 프로퍼티
- 런타임 보안이 필요하다: 접근 제한자만으로 해결되지 않음
주의할 점
접근 제한자가 런타임 보안을 보장하는 것은 아닙니다. 주로 TypeScript 수준의 설계 제약으로 이해하는 편이 정확합니다.
class User {
private token = "secret";
}
// private는 주로 설계 의도를 드러내는 도구다.참고 링크
1 sources