我在typescript + expressjs中构建一个简单的rest api。我想用类构建它,并且我坚持使用路由类。 我的想法是构建一个可以由特定路由器(IndexRouter)扩展的基类(baseRouter)。但是尝试这样做,我最终会从baseRouter而不是IndexRouter注册路由。 我做错了什么?
export class baseRouter {
protected static _inst: baseRouter;
protected _router: express.Router;
protected _routeBase: string = "/base";
protected constructor() { }
public static route(router: express.Router) {
if (typeof this._inst === 'undefined') this._inst = new this();
this._inst._router = router;
this._inst._registerRoutes();
}
protected _registerRoutes() {
this._router.get(this._routeBase, this._doGet);
console.log('Calling base route');
}
protected _doGet(req: express.Request, res: express.Response) {
res.status(200);
res.send('isBase');
}
}
export class indexRouter extends baseRouter {
protected _routeBase = "/index";
protected _registerRoutes() {
this._router.get(this._routeBase, this._doGet);
console.log('Calling index route');
}
protected _doGet(req: express.Request, res: express.Response) {
res.status(200);
res.send('isIndex');
}
protected _doPost(req: express.Request, res: express.Response) {
res.status(200);
res.send('isIndexPost');
}
}
两个类的输入方法是.route(路由器)。 理想情况下,我理解的解决方案将是:
BaseRouter.route() -> calls baseRouter._registerRoutes() -> ...
IndexRouter.route() -> calls indexRouter._registerRoutes() -> ...
这是否可以在没有重新声明.route()函数的情况下实现?
答案 0 :(得分:1)
问题在于这一行:
if (typeof this._inst === 'undefined') this._inst = new this();
当您第一次拨打BaseRouter.route()
时,此行会设置BaseRouter._inst
静态成员
但由于IndexRouter
扩展BaseRouter
,它也会继承静态成员,因此IndexRouter._inst
也存在,因此在该行中不会创建IndexRouter
的实例。< / p>
它在游乐场中运行良好的原因是它定位于es5
,您可能会定位es6
。
不同之处在于,在定位es6
时,类将转换为静态行为不同的es6
类。
要解决此问题,您可以执行以下操作:
public static route() {
if (typeof this._inst === 'undefined' || this._inst.constructor !== this) this._inst = new this();
this._inst._registerRoutes();
}
据我所知,有一个&#34;静态多态这个成员的伎俩,例如这失败了:
class BaseRouter<T extends BaseRouter<any>> {
protected static _inst: T;
...
}
由于:
Static members cannot reference class type parameters
所以我很确定你必须坚持:static _inst: baseRouter
。
您可以尝试在IndexRouter
中重新声明该成员:
class IndexRouter extends BaseRouter {
protected static _inst: IndexRouter;
...
}
你也可以有一个通用的getter:
class BaseRouter {
private static _inst: BaseRouter;
protected static _getInstance<T extends BaseRouter>(): T {
return this._inst as T;
}
...
}