TypeScript Parameter Decorators: Enhancing Function Behavior
Parameter decorators in TypeScript offer a powerful way to modify or annotate parameters of a method or constructor. This challenge will guide you through implementing a practical parameter decorator that logs the value of a specific parameter before a function is executed. This is a fundamental concept for understanding metaprogramming in TypeScript and building reusable code enhancement utilities.
Problem Description
Your task is to create a TypeScript parameter decorator named LogParam. This decorator will be applied to a specific parameter of a function. When the decorated function is called, the LogParam decorator should intercept the parameter's value and log it to the console with a descriptive message.
Key Requirements:
- Define the
LogParamdecorator: This decorator should be a function that can be applied to a parameter. - Parameter Logging: The decorator must log the value of the parameter it decorates to the console.
- Descriptive Output: The console output should clearly indicate which parameter's value is being logged (e.g., "Logging parameter 'paramName' with value: [value]").
- Function Execution: The original function should execute normally after the parameter has been logged.
- TypeScript Configuration: Ensure your
tsconfig.jsonis configured to enable experimental decorators.
Expected Behavior:
When a function decorated with LogParam is called, the console output should reflect the logging of the decorated parameter before the function's logic executes.
Edge Cases to Consider:
- What happens if the decorated parameter has a
nullorundefinedvalue? - How does the decorator handle different data types for the parameter?
Examples
Example 1:
function greet(message: string, @LogParam() name: string): void {
console.log(`Hello, ${name}!`);
}
greet("Welcome", "Alice");
Logging parameter 'name' with value: Alice
Hello, Alice!
Explanation:
The LogParam() decorator is applied to the name parameter. When greet is called with "Alice" as the name, the decorator intercepts this value, logs it to the console, and then the greet function proceeds to print "Hello, Alice!".
Example 2:
function processData(id: number, @LogParam() data?: string): void {
console.log(`Processing ID: ${id}`);
if (data) {
console.log(`Received data: ${data}`);
} else {
console.log("No data provided.");
}
}
processData(123);
processData(456, "sample");
Processing ID: 123
No data provided.
Logging parameter 'data' with value: undefined
Processing ID: 456
Received data: sample
Explanation:
In the first call, data is undefined. The decorator logs this. In the second call, data is "sample", and the decorator logs this before the function executes its logic.
Example 3: (Handling null values)
function updateStatus(@LogParam() status: string | null): void {
console.log(`Status updated to: ${status}`);
}
updateStatus("Active");
updateStatus(null);
Logging parameter 'status' with value: Active
Status updated to: Active
Logging parameter 'status' with value: null
Status updated to: null
Explanation:
The decorator correctly logs both a string value and null for the status parameter.
Constraints
- TypeScript Version: Ensure compatibility with TypeScript 4.0 or later.
- Decorator Implementation: The decorator must be implemented as a function using the standard TypeScript decorator syntax.
- Console Output: All logging should be directed to
console.log. - No External Libraries: Do not use any third-party libraries for implementing the decorator.
Notes
- Remember that parameter decorators receive three arguments:
target(the constructor function for static members or the prototype of the class for instance members),propertyKey(the name of the method), andparameterIndex(the index of the parameter). You will primarily useparameterIndexto identify which parameter is being decorated. - You will need to find a way to access the value of the parameter being decorated. Consider how function arguments are passed.
- Ensure your
tsconfig.jsonincludes"experimentalDecorators": trueand"emitDecoratorMetadata": true(thoughemitDecoratorMetadatais not strictly required for this specific problem, it's good practice when working with decorators).