typescript - 如何在运行时将参数传递给 TypeScript 装饰器?
问题描述
我想在运行时将参数传递给 TypeScript 装饰器,以便装饰方法将使用该参数,原始方法不需要它来运行,但装饰器可以。
我试图通过将参数传递给装饰方法,然后在原始方法的参数中的装饰器中找到它来实现这一点。
例如我尝试过的:
// calling a decorated method (nestJS code)
@Get('')
@UseGuards(JwtAuthGuard)
async getAll(@CurrentUser() user: User): Promise<any[]> {
//current user is a nestJS decorator extracts the user from the http header
const res = await this.whateverService.original(user);
return res;
}
// @MyDecorator usage
@MyDecorator()
async original(@user user: User): Promise<any>{
// return get all whatever
}
// @MyDecorator decorator
export function MyDecorator() {
return function (target: Object, propertyName: string | symbol, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
// get user param index
const userParamIndex = Reflect.getOwnMetadata(
userMetadataKey,
target,
propertyName
);
if (userParamIndex === undefined) {
throw new Error(`user undefined or missing @user decorator in method ${propertyName.toString()}`);
}
// override method descriptor with proxy method
descriptor.value = async function (...args: any[]) {
return new Promise(async (resolve, reject) => {
const user = args[userParamIndex];
let res;
try {
// await stuff using user arg;
res = await originalMethod();
} catch (err) {
reject(err);
} finally {
// await stuff;
resolve(res);
}
});
};
};
}
// @user decorator
export function user(
target: Object,
propertyKey: string | symbol,
parameterIndex: number
): void {
Reflect.defineMetadata(
userMetadataKey,
parameterIndex,
target,
propertyKey
);
}
我在这个实现中遇到的问题是user
原始参数被标记为declared but its value is never read.
在 IDE 中。
有没有办法让 IDE 知道它正在装饰器中使用?或者可能是一个更好的实现?
编辑
对于更多上下文,我添加的代码已简化,不包含所有功能。这一切的目的是:
- 从连接池中获取到 postgres 数据库的单个连接。
- 将 current_user_id 设置为会话运行时变量,以满足行级安全需求。
- 执行将执行数据库查询的原始方法。
- 重置会话运行时变量。
- 释放连接
- 返回原始方法的结果。
技术栈:NestJS 和 TypeORM。我正在尝试模仿TypeORM 的 Transaction 装饰器之类的东西,但具有额外的功能。
解决方案
推荐阅读
- python - 基于 2 个数据帧的 pandas 的高效数据操作
- stored-procedures - 获取程序的主体
- python - 如何在Networkx中从叶子到根的所有路径中的每个叶子连接到每个节点
- javascript - 使用 ckeditor 5 自定义构建和 vuejs 2
- indexing - 索引匹配的多个条件
- minio - 当一个minio节点的磁盘满了怎么办?
- php - 如何使用 Artifactory 作为我的 PHP 作曲家依赖项的缓存代理?
- go - 不能将 chan chan int 类型的变量用作 <-chan <-chan int 值
- python - 如何在 python CLI 中安装 IPSDK
- javascript - 引导日期选择器获取当前格式