【问题标题】:Unable to use super to call inherited class function无法使用super调用继承的类函数
【发布时间】:2019-04-07 23:57:33
【问题描述】:

我试图从子类调用父类的函数,但关键字super 是抛出错误。我正在使用打字稿,这是项目中 package.json 的 sn-p。

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

【问题讨论】:

  • 您注意到BaseController 曾经小写和大写吗?
  • @CristianTraìna 为基本控制器添加了缺少的导入语句,并在所有相同的情况下进行了尝试,仍然遇到问题。
  • 我对 TypeScript 不是很熟悉,但是对于普通的 JS,你需要在基类中有一个构造函数才能在子类中调用 super()
  • @Jacob 也试过了,没用
  • 尝试像这样创建函数:public async fetchUsers() {} 而不是将其分配给包含所有函数的变量

标签: javascript node.js typescript express tsconfig


【解决方案1】:

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

这里有几个问题。

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

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

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

只有箭头函数可以从父作用域获取super,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); });
}

还有一个问题是在不覆盖response 的类中引用super 是语义错误。子类已经继承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 类字段是构造函数主体的糖语法。

【讨论】:

【解决方案2】:

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

export class baseController {

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

    }
}


export class UsersController extends baseController {

  constructor() {
    super();
  }

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-27
    • 2016-03-12
    • 2016-06-24
    • 2014-10-11
    • 1970-01-01
    相关资源
    最近更新 更多