mercredi 21 février 2018

Typescript - Get uninitialized properties after compilation

I am currently writing a wrapper around socket.io. Comming from a very object-oriented background, I want to implement the concept of Models in my framework/wrapper.

If you happen to know socket.io you might know that you get the data that is associated with a event as a parameter, now I have implemented a custom routing system where the handler of the route gets the data in an express.js like request object.

The idea is to have model classes that look something like this:

class XRequestModel
  @v.String({ message: 'The username must be a string!' })
  public userName: string;
}

And the route event might look something like this:

@RouteConfig({ route: '/something', model: XRequestModel })
class XEvent extends Route {
  public on(req: Request<XRequestModel>, res: Response) {
    // Handle Event
  }
}

And to complete the example here is how the request object might look like:

class Response<T> {
  public data: T;
}

Now generics in typescript are very limited, since the type information is removed after compilation, I can not use the generic Request parameter ( which is the type of the model ) to get metadata from the model - Metadata, in this case, is the validation decorator. To overcome this issue I give a reference of the Model class to the RouteConfig of the RouteEvent, which is internally used, and would allow me to create instances of the model, get the properties and so on...

The idea here is to give the handler of a route, a request object with pre-validated, typesafe data.

The thing holding me back from this, is the fact that unused properties, get removed after compilation by typescript, So i can not get the metadata of the model. Initializing the class-property would solve this:

class XRequestModel
  @v.String({ message: 'The username must be a string!' })
  public userName: string = '';
}

But I think this makes for some very verbose syntax, and I dont want to force the user of this wrapper to init all the model properties.

A implementation side-note:

The user of the framework has to register the classes to a 'main' class and from there I can get the Route-class via decorator reflection.

When I try to get the properties of the model without initialized properties - First model example.

// Here the route.config.model refers to the model from the RouteConfig
Object.getOwnPropertyNames(new route.config.model());
>>> []

Here is what I get with initialized properties:

Object.getOwnPropertyNames(new route.config.model());
>>> [ 'userName' ]

Here a link to the github repository: https://github.com/FetzenRndy/SRocket Note that models are not implemented in this repo yet.





Aucun commentaire:

Enregistrer un commentaire