Currently, I am developing a middleware class for Express. Before delving into the details of the class, it's important to note that I will be injecting the middleware later by creating an instance of my "Authenticator" class and then using its method with
app.use(authInst.express)
The crucial aspect here is the execution context (this) of this function. This is the progress I have made so far:
Option 1
class Authenticator {
opts: IAuthOpts ;
express: RequestHandler| ErrorRequestHandler
constructor(opts: IAuthOpts){
this.opts = opts;
this.express = function(req: Request, res: Response, next: NextFunction){
if(this.opts.enabled) {
mainController(req, res, next, this.opts)
} else {
next();
}
}
}
}
This solution works fine, but I dislike having the function within the constructor as it seems like messy code. Placing the express method directly in the class like this:
Option 2 - Not functioning
class Authenticator {
opts: IAuthOpts;
constructor(opts: IAuthOpts){
this.opts = opts;
}
express(req, res, next){
if(this.opts.enabled) {
mainController(req, res, next, this.opts)
} else {
next();
}
}
}
will not work as the execution context from express will result in 'this' being undefined. Therefore, the following alternative must be considered:
Option 3
class Authenticator {
opts: IAuthOpts ;
express: RequestHandler| ErrorRequestHandler
constructor(opts: IAuthOpts){
this.opts = opts;
this.express = _express.bind(this);
}
private _express(req, res, next){
if(this.opts.enabled) {
mainController(req, res, next, this.opts)
} else {
next();
}
}
}
Presently, this solution seems optimal as it enables easy outsourcing of the method to another file while keeping files succinct. However, the downside is the use of bind. Personally, I prefer functions that return the same value when invoked with the same parameters regardless of their origin, which necessitates binding the class each time.
Is there a superior approach for externalizing a method from a TypeScript class without requiring the injection of the execution context via bind?