首页 > 解决方案 > 类型 ErrorConstructor 的 TypeScript 问题

问题描述

我正在尝试创建一个函数,该函数采用 ErrorConstructor 和消息,并通过一点转换的消息引发此错误。但是在尝试传递扩展基本错误的自定义错误构造函数时出现意外错误:

err<E extends ErrorConstructor>(Err: E, message: any): never {
    throw new Err(`'${message}': at line ${this.line}, at column ${this.column}`)
}

class LexerError extends Error {name="LexerError"}

err(LexerError, 'Invalid token: ${some_token}') //here is the error

错误:Argument of type 'typeof LexerError' is not assignable to parameter of type 'ErrorConstructor'. Type 'typeof LexerError' provides no match for the signature '(message?: string | undefined): Error'

标签: typescripttypesconstructor

解决方案


命名的类型在 TypeScript 标准库ErrorConstructor中定义为

interface ErrorConstructor {
    new(message?: string): Error; // construct signature
    (message?: string): Error; // call signature
    readonly prototype: Error;
}

因此,为了使某物成为一个ErrorConstructor,它不仅需要是具有构造签名的实际构造函数,需要是具有返回实例的调用签名的普通函数。ErrorLexerError只是一个构造函数,而不是一个普通的函数。

由于您只关心构造签名,因此您应该忘记ErrorConstructor类型并直接使用构造签名:

function err<E extends new (message?: string) => Error>(Err: E, message: any): never {
  throw new Err(
    `'${message}': minimal reproducible examples don't have unrelated errors`
  );
}

您可以验证现在一切都按预期工作:

class LexerError extends Error { name = "LexerError" }

err(LexerError, 'Invalid token: ${some_token}') // okay`

Playground 代码链接


推荐阅读