打字稿:"Outsourcing"方法。清洁的方式



我目前正在研究一个类,我在express中用作中间件。在我进入课程之前,请记住,稍后我将通过首先创建我的类"身份验证器"的实例,然后注入它的方法来

注入中间件
app.use(authInst.express)

因此,关键点将是此函数的执行上下文(this(。这是我到目前为止的代码

备选案文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();
}
}
}
}

这是有效的。然而,我不想在构造函数中编写函数,因为我发现它非常丑陋的代码。像这样将 express 方法直接放在类中

不工作

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();
}    
}
}

将无法工作,因为来自 Express 的执行上下文会给我这个未定义。所以剩下的就是使用这种替代方案

备选案文2

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();
}    
}
}

现在这也有效,并且是迄今为止我解决此问题的首选解决方案,因为将该方法外包到另一个文件并保持我的文件较小也很容易。缺点是绑定。我不是绑定的忠实粉丝,因为我希望我的函数返回相同的值,如果我使用相同的参数调用它们,无论它们从哪里调用,在这种情况下,您始终需要将类绑定到它。

有没有更好的解决方案从 TypeScript 类外包方法,但仍然不必使用 bind 注入执行上下文?

您可以使用箭头函数代替绑定:

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();
}    
}
}

如果随后要将实现移动到另一个文件,则定义一个函数,该函数将Authenticatorreqresnext一起作为普通参数,然后从箭头函数调用该函数可能最清楚:

class Authenticator {
opts:IAuthOpts ;
constructor(opts:IAuthOpts){
this.opts = opts;
}
express = (req, res, next) => otherFunction(this, req, res, next);
}
// In other file
function otherFunction(authenticator: Authenticator, req: Request, res: Response, next: NextFunction) { 
if(authenticator.opts.enabled) {
mainController(req, res, next, authenticator.opts)
} else {
next();
}    
}

如果这不是您要找的,请澄清问题。

最新更新