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

Jud*_*des 1 javascript node.js express typescript tsconfig

我试图从子类调用父类的函数,但关键字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"
  }
}
Run Code Online (Sandbox Code Playgroud)

父类

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: []
    });
  };
}
Run Code Online (Sandbox Code Playgroud)

儿童班

import BaseController from "../baseController";

export default class UsersController extends BaseController {

  constructor() {
    super();
  }

  public fetchUsers = async () => {
    return super.response("testing");
  };
}
Run Code Online (Sandbox Code Playgroud)

代码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"]
}
Run Code Online (Sandbox Code Playgroud)

Jac*_*cob 5

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

export class baseController {

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

    }
}


export class UsersController extends baseController {

  constructor() {
    super();
  }

  public async fetchUsers() {
    return super.response("testing");
  };
}
Run Code Online (Sandbox Code Playgroud)


Est*_*ask 5

这种情况是原型方法可能优于箭头类字段(实例方法)的几个原因之一,如本答案所述

这里有几个问题。

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

另一个问题是目标是 ES6。async被转译为生成器,而super不是被转译,这会导致错误的代码:

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

只有箭头函数可以super从父作用域获取,super不允许在非箭头函数内部使用。由于没有箭头生成器,super因此在生成器内使用无效。虽然 TypeScript 能够superasync 原型方法中正确处理:

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

另一个问题是,super在没有覆盖的类中引用response是语义错误。子类已经继承response。它可以用作this方法。

它应该是:

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

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

如果fetchUsers预期用作回调(这是箭头方法的唯一用途),则应将其绑定到this构造函数中的上下文:

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

  public async fetchUsers() {
    return this.response("testing");
  };
Run Code Online (Sandbox Code Playgroud)

其中fetchUsersclass 字段是构造函数体的糖语法。