我想编写一个 TypeScript 方法装饰器,它只能应用于具有某种类型的第一个参数的方法。这是我正在使用的代码库中的一种常见模式,用于传递具有数据库、指标、日志记录等句柄的请求上下文。我想编写一个装饰器,它需要请求上下文中的这些资源之一,但是否则与请求上下文的形状无关。
这是一个程式化的例子:
interface MyResource {
logMetricsEtc(...args: any): void;
}
interface HasResourceINeed {
myResource: MyResource;
}
function myDecorator<TFn extends ((tContext: HasResourceINeed, ...rest: any) => any)>(
_target: object,
key: string | symbol,
descriptor: TypedPropertyDescriptor<TFn>,
): TypedPropertyDescriptor<TFn> | void {
const originalHandler = descriptor.value!;
descriptor.value = function (this: any, context: HasResourceINeed, ...inputs: any) {
context.myResource.logMetricsEtc(...inputs);
return originalHandler.apply(this, [context, ...inputs]);
} as TFn;
}
Run Code Online (Sandbox Code Playgroud)
在使用中,strictFunctionTypes启用后,此装饰器在应用于原本看起来合理的方法时会导致编译错误:
interface ServiceContext {
myResource: MyResource;
otherResource: {
sendMessageEtc(msg: string): Promise<void>;
};
}
class MyBusinessClass { …Run Code Online (Sandbox Code Playgroud)