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'
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With