2017-09-26 3 views
7

TypeScriptがこのコードについて不平を言っているのはなぜですか?エラーハンドラでのTypeScriptマップの使用方法は?

class FooError extends Error { 
} 

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

タイプ 'typeof演算FooErrorは' 'ErrorConstructor' を入力する割り当て可能ではありません。

答えて

4

さて、ErrorConstructorの定義を見てみましょう:

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

、だから、ErrorConstructorは任意の文字列引数を取るコンストラクタである必要があり、それはまた、関数として呼び出し可能にする必要がありますプロトタイプErrorが必要です。さんがあなたのFooErrorクラスを見てみましょう:

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

それは、FooErrorErrorのサブタイプであるので、大丈夫ですFooErrorプロトタイプを、持っています。これはコンストラクタであり、ErrorConstructorであるスーパークラスErrorに委ねられているため、引数を受け入れます。しかし、関数として呼び出すことはできません。だからFooErrorErrorConstructorではありません。この時点で


、あなたはそれがErrorConstructorあることについて、あなたが実際にケアかどうかを判断する必要があります。 new FooError('msg')の代わりにFooError('msg')と呼ぶ予定ですか?疑わしい。その点については、コンストラクタのprototypeFooErrorであることに気をつけますか?おそらくそうではありません。その場合はErrorConstructorを使用しないでください。今、あなたのコードが動作する

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

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

そして、すべてが限り、同様となります代わりに、唯一のオプション-1-文字列引数のコンストラクターであることを気に以下のインターフェースを使用あなたはに準拠ケアについてFooErrorを行う場合(

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

:あなただけのコンストラクタとしてマップのキーを使用します、それは手配することができますが、もう少し面倒です。あなたが私に詳細を教えてもらいたいかどうか教えてください。)

とにかく、助けてください。がんばろう!

関連する問題