TypeScript
Decorator metadata
Learn type metadata with emitDecoratorMetadata.
What is emitDecoratorMetadata?
emitDecoratorMetadata: true carries the type information of decorated elements to runtime. Each decorator call gets a metadata parameter holding the target's type. This is required for dependency injection libraries (e.g. NestJS, TypeDI) to work.
{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}
experimentalDecorators must also be enabled.
Metadata format
With emitDecoratorMetadata on, TypeScript adds three metadata keys to the decorator call: design:type (property type), design:paramtypes (parameter types), and design:returntype (return type). This data is stored via Reflect.metadata.
// after compilation:
// __decorate([
// Reflect.metadata("design:type", Function),
// Reflect.metadata("design:paramtypes", [String])
// ], ...)
This is why the reflect-metadata polyfill is required.
Exercise Produce the metadata keys
Write a buildMetadataKeys function that returns the metadata key array based on hasType, hasParams, and hasReturn parameters. Print the result of buildMetadataKeys(true, true, false) joined with commas.
Show example solution
function buildMetadataKeys(hasType: boolean, hasParams: boolean, hasReturn: boolean): string[] {
const keys: string[] = [];
if (hasType) keys.push("design:type");
if (hasParams) keys.push("design:paramtypes");
if (hasReturn) keys.push("design:returntype");
return keys;
}
console.log(buildMetadataKeys(true, true, false).join(", "));
Test yourself
-
Which libraries specifically require emitDecoratorMetadata?
- Dependency injection libraries
- State management libraries
- Testing libraries
- Debugging libraries
Show answer
Dependency injection libraries — Dependency injection libraries (such as NestJS, TypeDI) rely on decorator metadata; debugging, state management, and testing libraries do not require decorator metadata.
-
Enable the metadata flag
{
"compilerOptions": {
"experimentalDecorators": true,
"____": true
}
}
Show answer
{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}
-
Decorator metadata parts
- emitDecoratorMetadata
- carries type info to runtime
- experimentalDecorators
- enables decorators
- design:type
- property type metadata
- reflect-metadata
- polyfill that stores metadata
Next lesson: Summary - Emit