I am currently in the process of creating a wrapper for socket.io. Coming from a strong object-oriented background, I aim to incorporate the idea of Models into my framework/wrapper.
For those familiar with socket.io, you may know that data associated with an event is typically passed as a parameter. In my custom routing system, however, the data is accessed within an express.js-like request object by the route handler.
The concept involves defining model classes like this:
class XRequestModel
@v.String({ message: 'The username must be a string!' })
public userName: string;
}
An example of how a route event might be structured:
@RouteConfig({ route: '/something', model: XRequestModel })
class XEvent extends Route {
public on(req: Request<XRequestModel>, res: Response) {
// Handle Event
}
}
Here is a representation of the request object:
class Request<T> {
public data: T;
}
Due to limitations with generics in typescript and the removal of type information after compilation, accessing metadata (such as validation decorators) from the model class is challenging. I address this by referencing the Model class in the RouteConfig of the RouteEvent internally to create instances of the model with properties intact.
The goal is to provide route handlers with pre-validated, type-safe data in the form of a request object.
One obstacle is that unused properties are removed after compilation in TypeScript, hindering access to model metadata. Initializing class properties resolves this:
class XRequestModel
@v.String({ message: 'The username must be a string!' })
public userName: string = '';
}
However, this approach leads to verbose syntax and imposes the burden of initializing all model properties on the user of the wrapper.
On the implementation side, users must register classes to a 'main' class from where the Route-class can be obtained through decorator reflection.
When attempting to retrieve properties of a model with uninitialized properties:
// Here the route.config.model refers to the model from the RouteConfig
Object.getOwnPropertyNames(new route.config.model());
>>> []
And with initialized properties:
Object.getOwnPropertyNames(new route.config.model());
>>> [ 'userName' ]
Feel free to visit the GitHub repository: https://github.com/FetzenRndy/SRocket Please note that models have not been implemented in this repository yet.
In essence, my question boils down to: How can I access the properties of a class with uninitialized properties post-compilation?