【问题标题】:How to use TypeScript Map with error handlers?如何将 TypeScript Map 与错误处理程序一起使用?
【发布时间】:2017-09-26 21:21:25
【问题描述】:

为什么 TypeScript 抱怨这段代码?

class FooError extends Error {
}

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

类型“typeof FooError”不可分配给类型“ErrorConstructor”。

【问题讨论】:

    标签: typescript


    【解决方案1】:

    好吧,我们来看看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
    

    它有一个FooError 原型,这很好,因为FooErrorError 的子类型。它是一个构造函数,它接受一个参数,因为它遵循超类Error,它是一个ErrorConstructor。但它不能作为函数调用。所以FooError 不是ErrorConstructor


    此时,您需要确定您是否真的关心它是ErrorConstructor。您是否打算将其称为FooError('msg') 而不是new FooError('msg')?我对此表示怀疑。就此而言,您是否关心构造函数的prototypeFooError 类型?可能不是。在这种情况下,不要使用ErrorConstructor。相反,请使用以下接口,它只关心作为一个可选的单字符串参数构造函数:

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

    现在你的代码可以工作了:

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

    一切都会好起来的,只要你只使用地图的键作为构造函数:

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

    (如果您确实关心FooError 符合ErrorConstructor,可以安排,但有点烦人。如果您希望我详细说明,请告诉我。)

    无论如何,希望对您有所帮助;祝你好运!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-23
      • 1970-01-01
      • 1970-01-01
      • 2010-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多