데코레이터는 클래스, 속성, 메서드 또는 매개변수의 동작을 추가 메타 정보 또는 구현의 변경을 통해 수정할 수 있게 해주는 특별한 주석입니다.
일반적으로 의존성 주입, 로깅, 유효성 검사, 캐싱 또는 Angular와 같은 프레임워크를 위한 메타데이터 선언을 위해 사용됩니다.
간단한 메서드 데코레이터의 예:
function Log(target: any, propertyKey: string, descriptor: PropertyDescriptor) { const original = descriptor.value; descriptor.value = function(...args: any[]) { console.log(`호출: ${propertyKey}(${JSON.stringify(args)})`); return original.apply(this, args); }; } class Example { @Log doSomething(a: number, b: number) { return a + b; } }
함정:
experimentalDecorators를 tsconfig에서 활성화해야 작동합니다.질문: "데코레이터의 매개변수를 타입으로 정의하여 적용되는 메서드의 타입을 보장할 수 있습니까?"
답변: 대부분의 경우 메타 프로그래밍의 동적 특성 때문에 데코레이터 적용 시점에서 타입을 정의하는 것은 불가능합니다. 그러나 제너릭과 추가 런타임 검사를 통해 유효성을 추가할 수 있지만 TypeScript 컴파일러는 구조 선언 단계에서 보장을 제공하지 않습니다.
예:
function MyDecorator(target: any, propertyKey: string, descriptor: TypedPropertyDescriptor<number>) { /* ... */ } // 컴파일러는 메서드가 number를 반환한다고 보장하지 않습니다.
이야기
많은 데코레이터가 있는 서비스 프로젝트에서 적용 순서를 잊어버려 property-데코레이터가 모든 매개변수보다 먼저 적용되었고, 이로 인해 Inject 메타데이터가 손실되고 실행 중 의존성을 해결할 수 없게 되었습니다.
이야기
개발자들이 클래스의 메서드가 아닌 일반 함수에 데코레이터를 적용하기로 결정했으며, 컴파일 오류와 런타임 효과가 없음을 보고 놀랐습니다. TypeScript 사양에서는 데코레이터가 클래스와 그 구성원에게만 적용됩니다.
이야기
TypeScript 버전 업데이트와 실험적 설정 이후 모든 데코레이터 메커니즘이 커스텀 DI 컨테이너에서 고장났습니다. 새로운 버전이 Reflect-metadata의 명시적 지원을 요구하여 모든 메타 정보가 상실되었습니다.