无法使用 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.response
。 super
指的是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 字段是构造函数主体的糖语法。
我正在尝试从 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.response
。 super
指的是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 字段是构造函数主体的糖语法。