Typescript: instanceof is broken when class extends Error type

Created on 9 Feb 2017  路  11Comments  路  Source: microsoft/TypeScript

TypeScript Version: 2.1.1

class BaseError extends Error {}
class Error1 extends BaseError {}

let error = new Error1();
console.log(error instanceof Error1);

Expected behavior:
prints true.

Actual behavior:
prints false.

Note:
This happens only when a type extends Error.
After removing extends Error from BaseError everything works as expected.

Links
Test case

Duplicate

Most helpful comment

What's the issue this is a duplicate of? I think this is still unresolved.

I'm trying to implement an error handler in angular 5, but without instanceof working it's difficult

All 11 comments

Unfortunately this is a change that we made to try to try to adopt a more standard-compliant emit so that we could enable Polymer to work with TypeScript.

For background, was an intentional change in 2.2 (see #12123 and the section on our wiki), but is difficult to overcome through compilation. I believe there's some conversation in #12790 for workarounds.

A workaround you can take now is create an intermediate class that you can extend from.

export interface MyErrorStatic {
    new (message?: string): RxError;
}
export interface MyError extends Error {}

export const MyError: MyErrorStatic = function MyError(this: Error, message: string) {
    const err = Error.call(this, message);
    this.message = message;
    this.stack = err.stack;
    return err;
} as any;

export class HttpError extends MyError {
    // ...
}

In TypeScript 2.2, you'll be able to set the prototype on your own.

// Use this class to correct the prototype chain.
export class MyError extends Error {
    __proto__: Error;
    constructor(message?: string) {
        const trueProto = new.target.prototype;
        super(message);

        // Alternatively use Object.setPrototypeOf if you have an ES6 environment.
        this.__proto__ = trueProto;
    }
}

Sorry for the inconvenience of this.

What's the issue this is a duplicate of? I think this is still unresolved.

I'm trying to implement an error handler in angular 5, but without instanceof working it's difficult

For anyone looking for a workaround that will let them unit test their custom error classes using instanceof (or chai/jasmine expectations based on it), I made a shim that does so: DanielSchaffer/ts-custom-error-shim

Ah, I ran into this issue yesterday. Definitely consumed several hours before I found this issue. Anyone have a good solution for this yet?

@cjam You can set the prototype yourself as noted here: https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work

Was this fixed?

Workaround, requires unique properties on each error:
function isError1(error: Error): error is Error1 { return (<Error1>error).attr1 !== undefined; }

source: http://www.typescriptlang.org/docs/handbook/advanced-types.html#user-defined-type-guards

I ran into this today. Is this a bug?

@DanielRosenwasser I think this should be re-opened; this feels seriously broken as-is.

Locking due to unproductive/repetitive discussion

Please read the FAQ entry for details

Was this page helpful?
0 / 5 - 0 ratings