I would like to extend the host object Error
to a custom UploadError
class. The following example fails when I compile:
class UploadError extends Error { constructor(message: string, private code: number) { super(message); } getCode(): number { return this.code; } }
When I run the TypeScript compiler tsc
I get the following error:
UploadError.ts(1,0): A export class may only extend other classes, Error is an interface.
It seems Error
is defined as an interface. If anyone knows what the name of the implementation is it would make me very happy :-)
function UploadError (message: string, code: number) { this.message = message; this.code = code; } UploadError.prototype = new Error(); UploadError.prototype.constructor = UploadError; UploadError.prototype.getCode = (): number => { return this.code; }
Just like object-oriented languages such as Java and C#, TypeScript classes can be extended to create new classes with inheritance, using the keyword extends . In the above example, the Employee class extends the Person class using extends keyword.
extends means it gets all from its parent. implements in this case it's almost like implementing an interface. A child object can pretend that it is its parent... but it does not get any implementation.
To declare a function that throws an error, set its return type to never . The never type is used for functions that never return a value, in other words functions that throw an exception or terminate execution of the program.
It's now possible to directly extend from the Error
class, the code in my original answer still works, but there's no longer a need for the export declare class Error
.
Most of the answers here don't meet my requirements. The originally accepted answer doesn't compile anymore since 0.9.5 with a duplicate identifier exception. And non of them really have a stack trace (a JavaScript issue, not TypeScript).
For me a more elegant solution is:
module YourModule { export declare class Error { public name: string; public message: string; public stack: string; constructor(message?: string); } export class Exception extends Error { constructor(public message: string) { super(message); this.name = 'Exception'; this.message = message; this.stack = (<any>new Error()).stack; } toString() { return this.name + ': ' + this.message; } } }
What you can do with it:
new Exception("msg") instanceof Error == true
class SpecificException extends Exception
catch (e) { console.log(e.stack); }
The only limitation I found was that you have to declare it in a module, and cannot make them global. For me this isn't an issue since I think a module helps in structuring, and they are there in any application I make.
One improvement you could make is strip your custom code from the stack trace, personally I think stacktraces are only for the eyes of developers, and they know where to look, so it's no big deal for me.
pay attention on the new changes in Typescript 2.1 - link
So you can extend the Error class but, as a recommendation, you need manually adjust the prototype immediately after any super(...) calls:
class FooError extends Error { constructor(m: string) { super(m); // Set the prototype explicitly. Object.setPrototypeOf(this, FooError.prototype); } sayHello() { return "hello " + this.message; } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With