1
votes

I have Typescript 4.0.2. In lib.es5.d.ts, there is the following fragment:

interface Error {
    name: string;
    message: string;
    stack?: string;
}

interface ErrorConstructor {
    new(message?: string): Error;
    (message?: string): Error;
    readonly prototype: Error;
}

declare var Error: ErrorConstructor;

I am able to use const err = new Error("some message");

I want to extend Error to add a property named statusCode to handle Http errors. I tried:

interface HttpException extends Error {
  // new(message?: string): Error;
  // (message?: string): HttpException;
  // readonly prototype: HttpException;
  statusCode?: number
}

But I am not able to use const e = new HttpException("Not found");. The error is 'HttpError' only refers to a type, but is being used as a value here. (ts2693)

Why can't HttpException be used in a similar manner to Error?

1
Because HttpException is only an interface. Error is a concrete object. declare var Error: ErrorConstructor; makes sure TS knows that.VLAZ
Btw, you can use any class as a type, but you can't use any type as a classcaptain-yossarian
@VLAZ Why is Error a concrete object? What do the three lines in ErrorConstructor mean?Old Geezer
@OldGeezer it's a concrete object because it has an implementation and thus you can call new with it. HttpException is just an interface, it defines the public API of an object but supplies no implementation for them. That's also what the three lines in ErrorConstructor define - the public interface. In that case, it says that you can call it with new (which takes an optional parameter), or call it as a function without new (also takes an optional parameter), finally there is a prototype property.VLAZ

1 Answers

1
votes

lib.es5.d.ts describes existing APIs (Error constructor in this case), but you're defining completely new one. Types/interfaces are erased at compile time hence the error. new keyword requires class or function that specifies the type of the object instance.

class HttpException extends Error {
    statusCode?: number
}

Playground