Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

instanceof is broken when class extends Error type #13965

Closed
tikurahul opened this issue Feb 9, 2017 · 11 comments
Closed

instanceof is broken when class extends Error type #13965

tikurahul opened this issue Feb 9, 2017 · 11 comments
Labels
Duplicate An existing issue was already created

Comments

@tikurahul
Copy link

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

@DanielRosenwasser
Copy link
Member

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.

@DanielRosenwasser DanielRosenwasser added the Duplicate An existing issue was already created label Feb 9, 2017
@tamf
Copy link

tamf commented Feb 17, 2017

Seriously...

https://media.giphy.com/media/sIE0hveuiwCNG/giphy.gif

@ghost
Copy link

ghost commented Feb 21, 2018

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

@DanielSchaffer
Copy link

DanielSchaffer commented Mar 3, 2018

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

@cjam
Copy link

cjam commented Apr 19, 2018

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

@taoyouh
Copy link

taoyouh commented May 13, 2018

@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

@odahcam
Copy link

odahcam commented Jun 9, 2018

Was this fixed?

@nediamond
Copy link

nediamond commented Jun 26, 2018

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

@stephengardner
Copy link

I ran into this today. Is this a bug?

@dhessler
Copy link

dhessler commented Aug 8, 2018

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

@RyanCavanaugh
Copy link
Member

RyanCavanaugh commented Aug 8, 2018

Locking due to unproductive/repetitive discussion

Please read the FAQ entry for details

@microsoft microsoft locked and limited conversation to collaborators Aug 8, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests