如果您将 TypeScript 设置为编译为 ES5 或其他一些 ES2015 之前的 JavaScript 版本,TypeScript 无法正确子类化 Error,因为在 ES2015 之前不可能这样做。因此,它会产生 Error 但不是 ErrorForbidden(在您的情况下)。
如果设置为 ES5 输出,则为您的代码生成的 JavaScript(如果我省略了 export 以便在 Playground 中使用它)看起来像这样:
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var ApiError = /** @class */ (function (_super) {
__extends(ApiError, _super);
function ApiError(message, httpCode) {
if (httpCode === void 0) { httpCode = 400; }
var _this = _super.call(this, message) || this;
_this.httpCode = httpCode;
return _this;
}
return ApiError;
}(Error));
var ErrorForbidden = /** @class */ (function (_super) {
__extends(ErrorForbidden, _super);
function ErrorForbidden(message) {
if (message === void 0) { message = 'Forbidden'; }
return _super.call(this, message, 403) || this;
}
return ErrorForbidden;
}(ApiError));
var error = new ErrorForbidden();
console.info(error instanceof ErrorForbidden); // false
console.info(error instanceof Error); // true
...显示false、true。
Live on the Playground
设置为 ES2015 输出时与此比较:
"use strict";
class ApiError extends Error {
constructor(message, httpCode = 400) {
super(message);
this.httpCode = httpCode;
}
}
class ErrorForbidden extends ApiError {
constructor(message = 'Forbidden') {
super(message, 403);
}
}
const error = new ErrorForbidden();
console.info(error instanceof ErrorForbidden); // false
console.info(error instanceof Error); // true
...显示true、true。
Live on the Playground