I'm currently attempting to make a class method decorator that functions perfectly with a regular class method compatible with a generic class method.
Here's the code in question at this typescript playground link:
abstract class WorkerBase {
log(...arguments_: unknown[]) {
console.log(arguments_);
}
}
const span =
<
This extends WorkerBase,
Target extends (this: This, ...arguments_: unknown[]) => Promise<unknown>,
>() =>
(target: Target, context: ClassMethodDecoratorContext<This, Target>) =>
async function replacementMethod(
this: This,
...originalArguments: unknown[]
) {
this.log(['called', this.constructor.name, context.name]);
return target.call(this, ...originalArguments);
};
class ExterneWorker extends WorkerBase {
@span()
protected async get<Return>() {
return undefined as unknown as Return;
}
}
Compiling this code returns the following error:
Decorator function return type '(this: ExterneWorker, ...originalArguments: unknown[]) => Promise<unknown>' is not assignable to type 'void | (<Return>() => Promise<Return>)'.
Type '(this: ExterneWorker, ...originalArguments: unknown[]) => Promise<unknown>' is not assignable to type '<Return>() => Promise<Return>'.
Type 'Promise<unknown>' is not assignable to type 'Promise<Return>'.
Type 'unknown' is not assignable to type 'Return'.
'Return' could be instantiated with an arbitrary type which could be unrelated to 'unknown'.
The issue arises when trying to use the span
decorator with a generic class method. While it works well with non-generic methods, it encounters problems with generics. Interpreting TypeScript's error message has proven challenging for me. It seems like there might be an issue with how I've defined the Return
parameter within the span decorator definition.