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

问题描述 投票:0回答:2

所以我有这些类来处理不同场景中的错误,如下所示:

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);
    }
}

然后我有这个更新抽象方法:

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.`);
        }
      ....

在我的控制器中,我试图捕获错误,然后获取它的实例,如下所示:

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

但是 statusCode 将始终返回 null,即使 StreamNotFound 扩展了 NotFound,并且 Notfound 正在被 Update 抽象方法使用。

如您所见,我在每个方法上添加了

Object.setPrototypeOf(this, StreamNotFound.prototype);
,所以我想知道为什么它没有按预期工作?

javascript typescript prototype
2个回答
5
投票

子类始终是

instanceof
本身及其任何父类。然而,反之则不然:父类不是
instanceof
它的任何子类。

在此示例中,

StreamNotFound instanceof NotFound === true
。然而,父类明确地not
instanceof
其任何子类。在这里,
NotFound instanceof StreamNotFound === false

在你的控制器中,你正在

throw
创建一个
NotFound
的实例,它永远不会是
instanceof StreamNotFound
,因为它在原型链中比它的子类更靠前。


在下面的简化示例中,

Bar
Foo
扩展为子类,因此:

  • 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));


0
投票

就我而言,我有一个根类

NodeCore
,其中有两个扩展该类的类:
Leaf
Choice
。我试图使用允许任一子类的类型:

type Node = Leaf | Choice;

然后我试图检查

instanceof
类型:

if (node instanceof Node) { ... }

这行不通。但是检查

原始类
instanceof 确实有效:

if (node instanceof NodeCore) { ... }
© www.soinside.com 2019 - 2024. All rights reserved.