검색
검색
공개 노트 검색
회원가입로그인
TypeScript 정복하기: 초심자에서 전문가로

15장: 고급 주제 – 데코레이터, 제네릭, 메타 프로그래밍

데코레이터: 클래스와 멤버에 새로운 힘을 불어넣다

클래스와 그 멤버를 꾸며주는 데코레이터는 TypeScript가 제공하는 대표적인 메타프로그래밍 도구입니다. 데코레이터를 이용하면 코드에 반복적으로 들어가는 인증, 로깅, 캐싱 등 다양한 부가 기능을 손쉽게 추가할 수 있습니다. ES6의 클래스 구조와 더불어 등장한 이 기능은, 클래스 선언부 혹은 그 안의 속성·메소드 위에 @ 기호와 함께 정의하여 적용합니다.

function Log(target: Object, propertyKey: string) {
  console.log(`${propertyKey}가 호출됨`);
}

class Example {
  @Log
  run() {
    // 실행 코드
  }
}

이렇게 간단히 꾸밀 수 있으며, 데코레이터 팩토리를 사용하면 동적으로 값도 전달 가능합니다. 여러 데코레이터를 조합하는 패턴도 최근 많이 사용되죠. 중요한 점은 데코레이터가 실제 런타임에 동작하며, 코드 외부에서 동작을 교체하거나, 메타데이터를 기록해 후처리에 활용할 수 있다는 점입니다.

제네릭: 타입의 유연함으로 코드 재사용 높이기

제네릭은 다양한 타입을 처리하는 코드에서 진가를 발휘합니다. 배열, 맵, 함수, 클래스 등 여러 곳에 활용 가능하며, 일관된 로직 위에 타입만 교체해 사용하도록 설계할 수 있습니다. 예를 들어, Array<T>처럼 구현자·사용자 누구에게나 타입 안정성을 제공하면서, 여러 데이터 타입과 자유롭게 조합할 수 있습니다.

function identity<T>(arg: T): T {
  return arg;
}

const num = identity<number>(10);
const str = identity<string>("hello");

함수, 인터페이스, 클래스 등 어디에서든 <T> 형태로 선언한 제네릭은, 실제 사용할 때 원하는 타입으로 구체화됩니다. 이 패턴 덕분에, 코드의 재사용성과 견고함은 동시에 올라갑니다.

메타프로그래밍: 타입과 코드, 경계를 넘어

메타프로그래밍은 프로그램이 자신의 구조나 동작을 해석하고, 조작하는 프로그래밍 기법입니다. TypeScript에선 데코레이터, 제네릭뿐 아니라, 고급 타입(조건부 타입, 매핑 타입 등)을 활용해 코드의 틀 자체를 동적으로 변화시킬 수 있습니다.

예를 들어, 인터페이스에 존재하는 모든 속성을 옵셔널로 만드는 유틸리티 타입은 다음과 같이 직접 정의할 수 있습니다.

type Partial<T> = {
  [P in keyof T]?: T[P];
};

함수를 인자로 받거나, 객체 구조를 동적으로 확장하거나, 데이터 직렬화·역직렬화 등 다양한 실무 상황에서 이처럼 타입 레벨에서 코드를 변환하는 전략이 활용됩니다.

전문가로 향하는 진짜 실력

타입스크립트의 진정한 힘은, 타입 시스템 위에서 동적으로 코드를 확장하고, 반복되는 패턴을 줄이며, 의도를 명확하게 드러내는 데 있습니다. 데코레이터로 실행 흐름을 제어하고, 제네릭으로 재사용성을 높이며, 메타프로그래밍 기법으로 코드의 한계를 확장해 보세요. 이 장에서 배운 고급 기술들을 익숙하게 다루게 되면, 타입스크립트를 „단순한 타입 추가 도구‟가 아니라 유지보수성과 생산성을 극대화해주는 근본적인 무기로 삼을 수 있습니다.


공유하기
카카오로 공유하기
페이스북 공유하기
트위터로 공유하기
url 복사하기