I have a sequence of nested function calls in my Typescript project. As Typescript does not support function level decorator, I wrote a customer decorator function to use with my functions.
(This is a sample scenario of files I am trying to sketch below to help you understand the structure of the actual project.)
decorator.ts:
const functionLoggingDecorator = (fn: Function) =>
(...args: any) => {
logger.info(`${fn.name} is called with args ${args}`);
return fn(...args);
}
Now, my functions are in different files.
file1.ts
const func1 = (a: number, b: number) => {
const sumWithLoggingDecorator = functionLoggingDecorator(sum);
const mulWithLoggingDecorator = functionLoggingDecorator(mul);
return sumWithLoggingDecorator(a, b) + mulWithLoggingDecorator(a, b)
}
const mainDriver = (a: number, b: number) => {
const withLoggingDecorator = functionLoggingDecorator(func1);
return withLoggingDecorator(a, b)
}
mainDriver(5, 6);
sum.ts
const sum = (a: number, b: number) => a + b;
mul.ts
const mul = (a: number, b: number) => a * b;
So... when it is executing, I get the first log as
'func1 is called with args 5,6'
But then in the next logs, the name of the functions are missing. The logs are:
This is for the sum
' is called with args 5,6
and, this is for the mul
' is called with args 5,6'
What I found is, if I use the decorator with functions that are in the same module i.e. in the same file, the log has the function name. But if they are in a separate file as I mentioned above, I don't get the function name.
I am not entirely sure, henceforth, asking the question here.
Is it happening because of hoisting functions? As a result, the names are missing?
I know, with strict mode I can't use callee, caller, argument. I also tried fn.toString() then apply a regex to extract the function name. But did not work as I used the arrow function pattern.
I found another way with creating an Error stack object mentioned in this StackOverflow answer. But I am not confident if this should be used in production code and if stack.split('\n')[2].trim() mentioned in the answer is always true for all cases.