Modern Decorators
Goal
Create a standard TypeScript method decorator that validates its application target and contributes to class metadata without accessing the class constructor.
Implementation
ts
import {
Methods,
getMetadataContainer,
} from '@litert/decorator';
function route(path: string): Methods.ICallbackFn {
return Methods.withArgsCheck((_method, ctx) => {
ctx.metadata!['route:' + String(ctx.name)] = path;
});
}
class Controller {
@route('/users')
public listUsers(): void {}
}
const metadata = getMetadataContainer(Controller);
console.log(metadata.get('route:listUsers'));Example code
| Decorator kind | Example |
|---|---|
| Class | Class.ts |
| Method | Method.ts |
| Property | Property.ts |
| Accessor | Accessor.ts |
| Getter | Getter.ts |
| Setter | Setter.ts |
| Static method | StaticMethod.ts |
| Static property | StaticProperty.ts |
| Static accessor | StaticAccessor.ts |
| Static getter | StaticGetter.ts |
| Static setter | StaticSetter.ts |
Notes
| Step | Reason |
|---|---|
Use Methods.withArgsCheck | The generated decorator throws when applied to the wrong kind of element. |
Write to ctx.metadata | Modern member decorators do not receive the owning class constructor or prototype. The metadata object is the shared class configuration container. |
Read through getMetadataContainer | Application code can read the completed class metadata after the class has been defined. |
For larger decorators, prefer a single metadata key that stores a structured class configuration object. Let class, instance member, and static member decorators add their own entries to that object, then read the final result from getMetadataContainer(YourClass).