Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript problem with types ErrorConstructor

I'm trying to create a function that takes ErrorConstructor and message and throws this error with a little bit transformed message. But I get an unexpected error when trying to pass custom error constructor that extends base error:

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

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'

like image 655
4nnihil4tor Avatar asked Feb 01 '26 20:02

4nnihil4tor


1 Answers

The type named ErrorConstructor is defined in the TypeScript standard library as

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

So in order for something to be an ErrorConstructor it needs to not only be an actual constructor with a construct signature, it also needs to be a normal function with a call signature that returns an Error instance. And your LexerError is only a constructor and not a normal function.

Since you only care about the construct signature, you should forget about the ErrorConstructor type and use the construct signature directly:

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`
  );
}

And you can verify that everything now works as expected:

class LexerError extends Error { name = "LexerError" }

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

Playground link to code

like image 193
jcalz Avatar answered Feb 03 '26 10:02

jcalz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!