Metadata
Some examples use the reflect-metadata
library which adds a polyfill for an experimental metadata API. This library is not yet part of the ECMAScript (JavaScript) standard. However, once decorators are officially adopted as part of the ECMAScript standard these extensions will be proposed for adoption.
You can install this library via npm:
npm i reflect-metadata --save
TypeScript includes experimental support for emitting certain types of metadata for declarations that have decorators. To enable this experimental support, you must set the emitDecoratorMetadata
compiler option either on the command line or in your tsconfig.json
:
Command Line:
tsc --target ES5 --experimentalDecorators --emitDecoratorMetadata
tsconfig.json:
{ "compilerOptions": { "target": "ES5", "experimentalDecorators": true, "emitDecoratorMetadata": true } }
When enabled, as long as the reflect-metadata
library has been imported, additional design-time type information will be exposed at runtime.
We can see this in action in the following example:
import "reflect-metadata"; class Point { x: number; y: number; } class Line { private _p0: Point; private _p1: Point; @validate set p0(value: Point) { this._p0 = value; } get p0() { return this._p0; } @validate set p1(value: Point) { this._p1 = value; } get p1() { return this._p1; } } function validate<T>(target: any, propertyKey: string, descriptor: TypedPropertyDescriptor<T>) { let set = descriptor.set; descriptor.set = function (value: T) { let type = Reflect.getMetadata("design:type", target, propertyKey); if (!(value instanceof type)) { throw new TypeError("Invalid type."); } } }
The TypeScript compiler will inject design-time type information using the @Reflect.metadata
decorator. You could consider it the equivalent of the following TypeScript:
class Line { private _p0: Point; private _p1: Point; @validate @Reflect.metadata("design:type", Point) set p0(value: Point) { this._p0 = value; } get p0() { return this._p0; } @validate @Reflect.metadata("design:type", Point) set p1(value: Point) { this._p1 = value; } get p1() { return this._p1; } }
NOTE Decorator metadata is an experimental feature and may introduce breaking changes in future releases.
Please login to continue.