Parameter Decorators
In this page:
Legacy Parameter Decorator Signature
The legacy (experimentalDecorators) parameter decorator signature receives the target object, the method name the parameter belongs to, and the parameter's numeric index within that method's argument list.
Example: Legacy Parameter Decorator Signature
function logParam(target: any, methodName: string, index: number) {
console.log(`Parameter ${index} of ${methodName} decorated`);
}
class Service {
greet(@logParam name: string) {
return "Hello " + name;
}
}
new Service().greet("Ravi");
Parameter Indexes
Because parameter decorators only get an index rather than a name, tooling built on them (like dependency-injection frameworks) typically has to also read the method's declared parameter types via reflection to make sense of that index.
Example: Parameter Indexes
function inject(target: any, methodName: string, index: number) {
console.log(`Injecting into parameter index ${index}`);
}
class Controller {
handle(@inject req: any, res: any) {
return "handled";
}
}
new Controller().handle({}, {});
Recording Parameter Metadata
A common use is recording which parameter index should receive an injected value in a metadata map, which some other part of the code (usually the method decorator) later reads when the method is actually invoked.
Example: Recording Parameter Metadata
const injectionMap = new Map<string, number[]>();
function injectable(target: any, methodName: string, index: number) {
const existing = injectionMap.get(methodName) ?? [];
existing.push(index);
injectionMap.set(methodName, existing);
}
class Repo {
find(@injectable id: number) {
return id;
}
}
new Repo();
console.log(injectionMap);
Parameter Decorator Limitations
Parameter decorators cannot change what value gets passed in or intercept the call directly — they can only attach metadata alongside the parameter, so any real behavior change has to happen in a paired method or class decorator.
Example: Parameter Decorator Limitations
function noteOnly(target: any, methodName: string, index: number) {
// Cannot change the value passed in -- only records metadata.
console.log(`Noted parameter ${index}, value unaffected`);
}
class Logger {
log(@noteOnly message: string) {
console.log(message);
}
}
new Logger().log("hello");
Modern Decorator Alternative
TypeScript's newer standard decorators proposal drops parameter decorators entirely in favor of attaching validation logic directly inside method decorators, so legacy parameter decorators are mostly seen in older dependency-injection codebases.
Example: Modern Decorator Alternative
// Legacy: parameter decorators (experimentalDecorators)
// Modern: validation moves into the method decorator itself
function validateArgs(target: any, context: ClassMethodDecoratorContext) {
return function (this: any, ...args: any[]) {
console.log("Validating all args together:", args);
return target.call(this, ...args);
};
}
class Service {
@validateArgs
process(id: number) {
return id;
}
}
new Service().process(1);
Chapter Quiz — Complete all 7 topics to unlock
0/7 topics done
Complete these topics first: