无法使用超级调用继承的类函数

时间:2018-11-04 11:59:56

标签: javascript node.js typescript express 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"
  }
}

父类

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: []
    });
  };
}

子类

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"]
}

2 个答案:

答案 0 :(得分:4)

this answer中所述,这种情况是原型方法可能比箭头类字段(实例方法)更可取的几个原因之一。

这里有几个问题。

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

另一个问题是目标是ES6。 async被编译到生成器,而super没有被编译,这导致代码不正确:

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

只有箭头函数可以从父范围获得super,非箭头函数中不允许super。由于没有箭头生成器,因此super的使用在生成器内部无效。虽然TypeScript能够在super prototype 方法中正确处理async

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

另一个问题是,在不覆盖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");
  };
}

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

答案 1 :(得分:2)

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

export class baseController {

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

    }
}


export class UsersController extends baseController {

  constructor() {
    super();
  }

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