无法使用 super 调用继承的 class 函数

Unable to use super to call inherited class function

我正在尝试从 child 调用 parent class 的函数,但关键字 super 抛出错误。我正在使用打字稿,这里是项目 package.json 的片段。

{
  "scripts": {
    "build": "tsc",
    "start": "nodemon",
    "prod": "npm run build && npm run start"
  },
  "dependencies": {
    "body-parser": "^1.18.3",
    "dotenv": "^6.1.0",
    "express": "^4.16.4"
  },
  "devDependencies": {
    "@types/body-parser": "^1.17.0",
    "@types/dotenv": "^4.0.3",
    "@types/express": "^4.16.0",
    "@types/node": "^10.12.2",
    "nodemon": "^1.18.5",
    "ts-node": "^7.0.1",
    "tslint": "^5.11.0",
    "typescript": "^3.1.6"
  }
}

parentclass

export default class baseController {

  public response = (message = "", status = 200) => (
    req: Request,
    res: Response
  ) => {
    return res.status(status).send({
      status: true, // true if success, false if faliure
      message: message, // message to display incase of error
      payload: []
    });
  };
}

childclass

import BaseController from "../baseController";

export default class UsersController extends BaseController {

  constructor() {
    super();
  }

  public fetchUsers = async () => {
    return super.response("testing");
  };
}

代码在行 return super.response("testing"); 上崩溃并出现错误 super keyword unexpected here

这是我的tsconfig.json

{
  "compilerOptions": {
    "module": "commonjs",
    "esModuleInterop": true,
    "target": "es6",
    "noImplicitAny": true,
    "moduleResolution": "node",
    "sourceMap": true,
    "outDir": "./dist",
    "pretty": true,
    "baseUrl": "./src",
    "alwaysStrict": true,
    "paths": {
      "*": ["node_modules/*", "src/types/*"]
    }
  },
  "include": ["src/**/*.ts"],
  "exclude": ["node_modules"]
}

您的问题在于您如何创建 class 的函数。 应该是这样的:

export class baseController {

    public response(message = "", status = 200) { 

    }
}


export class UsersController extends baseController {

  constructor() {
    super();
  }

  public async fetchUsers() {
    return super.response("testing");
  };
}

这种情况是原型方法优于箭头 class 字段(实例方法)的几个原因之一,如 .

中所述

这里有几个问题。

一个问题是没有super.responsesuper指的是parentclass原型,而response是实例方法。

还有一个问题就是目标是ES6。 async 被转译为生成器,而 super 未被转译,这导致代码不正确:

fetchUsers.a = () => __awaiter(this, void 0, void 0, function* () { return super.response("testing") });

只有箭头函数可以从 parent 作用域得到 super,non-arrow 函数内部不允许 super。由于没有箭头生成器,super 在生成器中使用是无效的。虽然 TypeScript 能够在 async prototype 方法中正确处理 super

fetchUsers() {
    const _super = name => super[name];
    return __awaiter(this, void 0, void 0, function* () { _super.response("testing").call(this); });
}

还有一个问题是,在 class 中引用 super 并没有覆盖 response 是语义错误。 Child class 已经继承了 response。它可以用作 this 方法。

应该是:

export default class baseController {
  public response(message = "", status = 200) (...) { ... }
}

export default class UsersController extends BaseController {
  public async fetchUsers() {
    return this.response("testing");
  };
}

如果 fetchUsers 被期望用作回调(这是箭头方法唯一好的用途),它应该绑定到构造函数中的 this 上下文:

  public fetchUsers = this.fetchUsers.bind(this);

  public async fetchUsers() {
    return this.response("testing");
  };

其中 fetchUsers class 字段是构造函数主体的糖语法。