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
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
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