'How to read properties in typescript after using Object.defineProperty?
I have the following code on typescript playground and a few questions come up that I am not sure how to get working
class PathInfo {
functionName: string;
httpPath: string;
httpMethod: string;
constructor(functionName: string, httpPath: string, httpMethod: string) {
this.functionName = functionName;
this.httpPath = httpPath;
this.httpMethod = httpMethod;
}
toString(): string {
return "PathInfo["+this.functionName+","+this.httpPath+","+this.httpMethod+"]";
}
}
class AuthRequest {}
class AuthResponse {}
class LoginRequest {}
class LoginResponse {}
const path: any = (thePath: string, type: any) => {
return (target: Function, memberName: string, propertyDescriptor: PropertyDescriptor) => {
const pathMeta = new PathInfo(memberName, path, type);
Object.defineProperty(target, memberName+'pathInfo', {
value: pathMeta,
writable: false
});
//How do I access the stored pathMeta
//console.log("target="+target.pathInfo);
console.log("member="+memberName);
console.log("props="+propertyDescriptor);
}
}
class AuthApiImpl {
@path("/authenticate", AuthResponse)
authenticate(request: AuthRequest): Promise<AuthResponse> {
throw new Error("all this is generated by factory.createApiImpl");
}
@path("/login", LoginResponse)
login(request: LoginRequest): Promise<LoginResponse> {
throw new Error("all this is generated by factory.createApiImpl");
}
};
function printMethods(obj: any) {
console.log("starting to print methods");
for (var id in obj) {
console.log("id="+id);
try {
//How do I access the stored pathMeta here FOR EACH METHOD ->
//console.log("target="+target.pathInfo);
if (typeof(obj[id]) == "function") {
console.log(id+":"+obj[id].toString());
}
} catch (err) {
console.log(id + ": inaccessible"+err);
}
}
}
console.log("starting to run")
const temp = new AuthApiImpl();
printMethods(temp);
console.log("done")
- line 64-65, how to read the property that I set
- line 40-41, how to read the property that I set
- line 58-74, why is this not printing any functions? I want to print all functions and I do NOT want to print properties (just functions)
- line 33, Can I access the class name at this point?
- line 35, I thought target was a function and would be authorize, then login, BUT if I define the property as JUST 'pathInfo', I get an error that the property is already defined on the target(This implies the target is the class not the function?). I am so confused.
Terribly sorry as I try to focus on a single question, but this one test of writing decorators has given me more questions than answers as I delve into the typescript world.
How can I tweak the code to play more here?
A goal here is as developers define the APIs of other microservices, I can capture a bunch of meta information and store it SOMEWHERE I can use later in startup code. I do not care where I store that really, but just need a clean way of knowing the class I want to extend, the methods, the return types, the http path, etc.
Solution 1:[1]
How to get methods of a class
You still can't grab the method names even if you remove the decorator. This isn't a TypeScript specific question.
You need to get the properties of the prototype, not just the object itself.
function printMethods(obj: any) {
console.log("starting to print methods");
const objProto = Object.getPrototypeOf(obj);
console.log(Object.getOwnPropertyNames(objProto));
}
How to access class names
Don't think this is possible with decorators at the moment, but it should be straightforward to just pass in your class name as a string.
Similar issue: TypeScript class decorator get class name
Open issue on GitHub: https://github.com/microsoft/TypeScript/issues/1579
"property is already defined on the target"
Notice if you run the code above you get the following in console.log:
["constructor", "authenticate", "login", "authenticatepathInfo", "loginpathInfo"]
I also want to point out that if you don't even initialize an instance of the class, you'll still get the same error.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Phil |
