如何让TypeScript类方法装饰器适配泛型类方法?
问题分析
原装饰器的类型约束仅适配非泛型异步方法,当作用于带泛型参数的方法时,替换函数返回的Promise<unknown>无法匹配原方法的Promise<Return>(Return是任意泛型类型,unknown不能赋值给任意类型),导致类型不兼容报错。
解决方法
修改装饰器的类型定义,使其兼容带泛型参数的方法:
- 将
Target的类型定义为支持泛型的异步函数类型,保留原方法的泛型参数和参数列表 - 替换函数也声明为泛型函数,确保返回类型与原方法的泛型返回值对齐
修改后的代码:
abstract class WorkerBase { log(...arguments_: unknown[]) { console.log(arguments_); } } const span = <This extends WorkerBase>() => <Target extends <R, Args extends any[]>(this: This, ...args: Args) => Promise<R>>( target: Target, context: ClassMethodDecoratorContext<This, Target> ) => { return async function replacementMethod<R, Args extends any[]>( this: This, ...originalArguments: Args ): Promise<R> { this.log(['called', this.constructor.name, context.name]); return target.call(this, ...originalArguments); } as Target; }; class ExterneWorker extends WorkerBase { @span() protected async get<Return>() { return undefined as unknown as Return; } }
关键说明
- 调整
Target的类型为<R, Args extends any[]>(this: This, ...args: Args) => Promise<R>,明确它是一个带泛型参数的异步方法 - 替换函数
replacementMethod同样声明泛型R和Args,保证返回类型Promise<R>与原方法的泛型返回值匹配 - 最后用
as Target断言替换函数的类型,让TypeScript确认它与原方法类型一致
内容的提问来源于stack exchange,提问作者mat
相关产品推荐
相关产品推荐

