"데코레이터는 클래스가 정의되는 순간, 붙어 있는 요소의 동작을 감싸거나 초기화에 참여하는 함수야."
값과 문맥을 받는 함수
현재 데코레이터 모델에서 함수는 장식할 값과 문맥 객체를 받아. 메서드 데코레이터라면 첫 인자가 원래 메서드이고 둘째 인자가 ClassMethodDecoratorContext야. 문맥에는 이름, 요소 종류, 정적·비공개 여부와 접근 도구가 들어 있어.
데코레이터는 대체 값을 반환하거나 아무것도 반환하지 않을 수 있어. 메서드의 대체 함수를 반환하면 호출을 감싸 로깅이나 시간 측정을 더할 수 있고, undefined를 반환하면 원래 메서드가 그대로 남아. 모든 일은 인스턴스 호출 때가 아니라 클래스 정의와 초기화 규칙에 맞춰 연결돼.
어디에 붙일 수 있을까
TC39 Stage 3 모델은 클래스, 메서드, getter, setter, 필드, auto-accessor 데코레이터를 다뤄. 접근자는 지원되지 않는다는 오래된 문장을 믿으면 안 돼. getter와 setter는 각각 장식할 수 있고, accessor 키워드로 만든 auto-accessor도 전용 문맥과 반환 모양을 가져.
반면 매개변수 데코레이터는 이 모델에 포함되지 않아. TypeScript의 레거시 experimentalDecorators 모드와 그 생태계에서는 볼 수 있지만, TypeScript 5.0부터 플래그 없이 사용하는 새 모델과 같은 계약이 아니야.
레거시 모드와 섞지 않기
experimentalDecorators는 더 오래된 제안의 호출 규칙을 구현해. 새 모델은 값과 문맥 객체를 전달하고 emitDecoratorMetadata 및 매개변수 데코레이터와 호환되지 않아. 기존 라이브러리가 어느 모델을 요구하는지 확인한 뒤 설정과 데코레이터 함수를 한쪽에 맞춰야 해.
새 코드는 현재 모델을 우선하되, 프레임워크가 레거시 메타데이터에 의존한다면 무작정 플래그를 지우지 마. 호출 인자와 반환 규칙이 달라 기존 데코레이터가 그대로 작동한다고 보장할 수 없어.
초기화 훅은 addInitializer
문맥 객체의 addInitializer는 클래스나 인스턴스 초기화 시점에 실행할 작업을 등록해. 예를 들어 메서드를 인스턴스에 바인딩하는 데 사용할 수 있어. 존재하지 않는 finishedHook 같은 이름을 외우지 말고, 장식 대상별 문맥 타입이 제공하는 실제 필드를 확인해.