Open laziel opened 7 years ago
타입스크립트 컴파일러는 "데코레이터 메타데이터"라는 실험적인 기능을 지원한다. 클래스 정의할 때 데코레이터에 정보를 전달하기 위해 생성된다.
예를 들어, 아래와 같은 타입스크립트 코드는
function paramDec(target: any, methodName: string, paramIndex: number) {} class testA { print(@paramDec is: number, name: string) : number { return 1000; } }
아래와 같은 자바스크립트로 변환된다.
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; function paramDec(target, methodName, paramIndex) { } var testA = (function () { function testA() { } testA.prototype.print = function (is, name) { return 1000; }; return testA; }()); __decorate([ __param(0, paramDec) ], testA.prototype, "print", null);
이 코드를, tsconfig.json 파일에 emitDecoratorMetadata: true 옵션을 주어 컴파일하면 아래와 같이 __decorate() 함수 호출시 추가적인 정보가 전달되는 것을 확인할 수 있다.
tsconfig.json
emitDecoratorMetadata: true
__decorate()
... var testA = (function () { function testA() { } testA.prototype.print = function (is, name) { return 1000; }; return testA; }()); __decorate([ __param(0, paramDec), __metadata('design:type', Function), __metadata('design:paramtypes', [Number, String]), __metadata('design:returntype', Number), ], testA.prototype, "print", null);
데코레이터에서 추가적인 정보를 사용하기 위해 서드파티 라이브러리 reflect-metadata를 사용해야 한다. 이 라이브러리는 아직 ECMAScript 표준에 포함되지는 않았지만 데코레이터가 공식적으로 표준 규격에 포함될 때에는 이 확장들 또한 함께 포함되도록 제안될 것이다. #
reflect-metadata
타입스크립트 컴파일러에 의해 자동으로 생성되는 메타데이터를 런타임에 얻을 수 있는것은 유용하다.
class Greeter { greeting: string; constructor(message: string) { this.greeting = message; } @validate greet(@required name: string) { return "Hello " + name + ", " + this.greeting; } }
import "reflect-metadata"; const requiredMetadataKey = Symbol("required"); function required(target: Object, propertyKey: string | symbol, parameterIndex: number) { let existingRequiredParameters: number[] = Reflect.getOwnMetadata(requiredMetadataKey, target, propertyKey) || []; existingRequiredParameters.push(parameterIndex); Reflect.defineMetadata(requiredMetadataKey, existingRequiredParameters, target, propertyKey); } function validate(target: any, propertyName: string, descriptor: TypedPropertyDescriptor<Function>) { let method = descriptor.value; descriptor.value = function () { let requiredParameters: number[] = Reflect.getOwnMetadata(requiredMetadataKey, target, propertyName); if (requiredParameters) { for (let parameterIndex of requiredParameters) { if (parameterIndex >= arguments.length || arguments[parameterIndex] === undefined) { throw new Error("Missing required argument."); } } } return method.apply(this, arguments); } }
@required 파라미터 데코레이터에서 메타데이터에 대상 파라미터를 필수 항목으로 마킹해놓고, @validate 메소드 데코레이터에서 이 메타데이터를 갖고 검사하는 예제.
@required
@validate
타입스크립트 컴파일러는 "데코레이터 메타데이터"라는 실험적인 기능을 지원한다. 클래스 정의할 때 데코레이터에 정보를 전달하기 위해 생성된다.
예를 들어, 아래와 같은 타입스크립트 코드는
아래와 같은 자바스크립트로 변환된다.
이 코드를,
tsconfig.json
파일에emitDecoratorMetadata: true
옵션을 주어 컴파일하면 아래와 같이__decorate()
함수 호출시 추가적인 정보가 전달되는 것을 확인할 수 있다.데코레이터에서 추가적인 정보를 사용하기 위해 서드파티 라이브러리
reflect-metadata
를 사용해야 한다. 이 라이브러리는 아직 ECMAScript 표준에 포함되지는 않았지만 데코레이터가 공식적으로 표준 규격에 포함될 때에는 이 확장들 또한 함께 포함되도록 제안될 것이다. #타입스크립트 컴파일러에 의해 자동으로 생성되는 메타데이터를 런타임에 얻을 수 있는것은 유용하다.
@required
파라미터 데코레이터에서 메타데이터에 대상 파라미터를 필수 항목으로 마킹해놓고,@validate
메소드 데코레이터에서 이 메타데이터를 갖고 검사하는 예제.