I'm trying to trace method calls in a Typescript class. Similar to: https://github.com/aiteq/trace
The code prints out the method trace correctly for the greet1
method, but not for the greet2
arrow function. I believe it's treated as a class property.
Any pointer on how I can print out the trace for the greet2
function?
Output:
> ts-node test.ts
getOwnPropertyNames - methodName: constructor
getOwnPropertyNames - methodName: greet1
Call Greeter.greet1, args: ["test1"]
test1
test2
Code:
function logClass(target: any) {
if (target.prototype) {
Object.getOwnPropertyNames(target.prototype).forEach((methodName: string) => {
const original = target.prototype[methodName]
console.log(`getOwnPropertyNames - methodName: ${methodName}`)
if (typeof original !== 'function' || methodName === 'constructor') {
return
}
target.prototype[methodName] = function (...args: any[]) {
const ret = original.apply(this, args)
console.log(`Call ${target.name}.${methodName}, args: ${JSON.stringify(args)}`)
return ret
}
})
}
return target
}
@logClass
class Greeter {
public greet1(s: string) {
return s
}
public greet2 = (s: string) => {
return s
}
}
const greeter = new Greeter()
console.log(greeter.greet1('test1'))
console.log(greeter.greet2('test2'))
This is not possible if you look at generated code, you will see that arrow functions are created in the constructor, they are not part of prototype.
So when decorator runs, it has no idea about the arrow function.
For this, you have to create another decorator like @logMethod
and apply it on the method declaration. That might work as in that case, decorator will be applied on a property, arrow function is essentially a property.