为什么 TypeScript 中的 instanceof 不适用于继承类?

lau*_*ent 2 instanceof typescript

我有以下课程:

class ApiError extends Error {
    httpCode: number
    constructor(message:string, httpCode:number = 400) {
        super(message);
        this.httpCode = httpCode;
    }
}

export class ErrorForbidden extends ApiError {
    constructor(message:string = 'Forbidden') {
        super(message, 403);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我创建一个实例,如下所示:

const error = new ErrorForbidden();
console.info(error instanceof ErrorForbidden); // false
console.info(error instanceof Error); // true
Run Code Online (Sandbox Code Playgroud)

因此,它似乎检测到它是 的实例,Error但不是 的实例,ErrorForbidden即使这就是我创建它的方式。

知道为什么它不起作用吗?以及如何让它发挥作用?

T.J*_*der 6

如果您将 TypeScript 设置为编译为 ES5 或其他 ES2015 之前版本的 JavaScript,则 TypeScript 无法正确子类化,Error因为在 ES2015 之前不可能这样做。因此,它会产生一些Error不是 an的东西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
Run Code Online (Sandbox Code Playgroud)

...这表明falsetrue

操场上的生活

与设置为 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
Run Code Online (Sandbox Code Playgroud)

...这表明truetrue

操场上的生活