简体   繁体   English

为什么 instanceof 在 Typescript 中没有按预期工作?

[英]Why is instanceof not working as expected in Typescript?

So I have these classes that I use to handle errors in different scenerios like so:所以我有这些类来处理不同场景中的错误,如下所示:

export class APIError extends Error {
    public readonly statusCode: number;
    public readonly message: string;

    constructor(statusCode?: number, message?: string) {
        super(message);
        Object.setPrototypeOf(this, APIError.prototype);

        if (typeof statusCode === 'string') {
            message = statusCode;
            statusCode = null;
        }

        this.statusCode = statusCode || 500;
        this.message = message || 'Internal Server Error';
    }

    public toJSON(): JsonData {
        return {
            statusCode: this.statusCode,
            message: this.message,
        };
    }
}

export class NotFound extends APIError {
    constructor(message?: string) {
        super(404, 'Not Found');
        Object.setPrototypeOf(this, NotFound.prototype);
    }
}

export class StreamNotFound extends NotFound {
    constructor() {
        super('Stream Not Found');
        Object.setPrototypeOf(this, StreamNotFound.prototype);
    }
}

And then I have this update abstract method:然后我有这个更新抽象方法:

public update(id: string, updateThing: T): T {
        if (!updateThing) return;

        const thing: T = this.get(id);
        if (!thing) {
            throw new NotFound(`${this.displayName} could not be found.`);
        }
      ....

In my controller, I'm trying to catch the error and then get it's instance like so:在我的 controller 中,我试图捕捉错误,然后得到它的实例,如下所示:

} catch (e) {
            const statusCode = (e instanceof StreamNotFound) ? 404 : null;
            throw HttpController.handleError(e, statusCode);
        }

But statusCode will always return null, even though streamNotFound extends NotFound, and Notfound is being used by the Update abstract method.但是 statusCode 将始终返回 null,即使 streamNotFound 扩展了 NotFound,并且 Update 抽象方法正在使用 Notfound。

As you can see, I'm adding the Object.setPrototypeOf(this, StreamNotFound.prototype);如您所见,我添加了Object.setPrototypeOf(this, StreamNotFound.prototype); on each of the methods, so I'm wondering why it is not working as expected?在每种方法上,所以我想知道为什么它没有按预期工作?

A subclass will always be an instanceof itself and any of its parent classes.子类将始终是其自身及其任何父类的instanceof However, the reverse is not true: a parent class is not an instanceof any of its subclasses.然而,反之则不然:父 class 不是其任何子类的instanceof

In this example, StreamNotFound instanceof NotFound === true .在此示例中, StreamNotFound instanceof NotFound === true However, a parent class is explicitly not instanceof any of its subclasses.但是,父 class 明确不是其任何子类的instanceof Here, NotFound instanceof StreamNotFound === false .在这里, NotFound instanceof StreamNotFound === false

In your controller, you're throw ing an instance of NotFound , which will never be an instanceof StreamNotFound , as it's further up in the prototype chain than its subclasses.在您的 controller 中,您正在throw NotFound的实例,它永远不会是instanceof StreamNotFound ,因为它在原型链中比它的子类更靠前。


In the simplified example below, Bar extends Foo as a subclass, thus:在下面的简化示例中, BarFoo扩展为子类,因此:

  • Foo instanceof Foo === true
  • Bar instanceof Foo === true
  • Bar instanceof Bar === true
  • Foo instanceof Bar === false

 class Foo { constructor() { } } class Bar extends Foo { constructor() { super(); } } const obj1 = new Foo(); const obj2 = new Bar(); console.log("Bar instanceof Bar: " + (obj2 instanceof Bar)); console.log("Bar instanceof Foo: " + (obj2 instanceof Foo)); console.log("Foo instanceof Bar: " + (obj1 instanceof Bar));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM