How to use TypeScript Map with error handlers?

Why is TypeScript complaining about this code?

class FooError extends Error { } const map = new Map<ErrorConstructor, any> ([ [Error, 'do this'], [FooError, 'do that'] ]) 

Type 'typeof FooError' is not assigned to type 'ErrorConstructor'.

+7
typescript
source share
1 answer

Ok, look at the definition of ErrorConstructor :

 interface ErrorConstructor { new(message?: string): Error; // is a constructor (message?: string): Error; // is callable readonly prototype: Error; // has an Error prototype } 

So, ErrorConstructor must be a constructor that takes an optional string argument, and must also be called as a function, and it must have a Error prototype. Take a look at your FooError class:

 class FooError extends Error { } FooError.prototype; // okay, type FooError new FooError("okay"); // okay FooError("oops"); // error 

It has a FooError prototype, which is great, because FooError is a subtype of Error . This is a constructor, and it takes an argument, since it overloads the superclass Error , which is ErrorConstructor . But this is not called a function. Thus, FooError not an ErrorConstructor .


At this point, you need to decide whether you really care that it is an ErrorConstructor . Do you plan to call it FooError('msg') instead of new FooError('msg') ? I doubt it. In this regard, do you care that the prototype constructor is of type FooError ? Probably no. In this case, do not use ErrorConstructor . Instead, use the following interface, which only cares about being a constructor with an optional single-line-arg:

 interface NoFrillsErrorConstructor { new(message?: string): Error; } 

Now your code will work:

 const map = new Map<NoFrillsErrorConstructor, any> ([ [Error, 'do this'], [FooError, 'do that'] ]) 

And everything will be fine if you use only map keys as constructors:

 map.forEach((val, err) => { err.prototype; // exists, but is type any. Who cares, right? new err(); // okay err(); // not okay }) 

(If you care about a FooError corresponding to ErrorConstructor , this can be organized, but it is a bit more annoying. Let me know if you want me to clarify.)

Anyway, hope this helps; good luck!

+4
source share

All Articles