首页 > 解决方案 > 如何在运行时将参数传递给 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 知道它正在装饰器中使用?或者可能是一个更好的实现?

编辑

对于更多上下文,我添加的代码已简化,不包含所有功能。这一切的目的是:

  1. 从连接池中获取到 postgres 数据库的单个连接。
  2. 将 current_user_id 设置为会话运行时变量,以满足行级安全需求。
  3. 执行将执行数据库查询的原始方法。
  4. 重置会话运行时变量。
  5. 释放连接
  6. 返回原始方法的结果。

技术栈:NestJS 和 TypeORM。我正在尝试模仿TypeORM 的 Transaction 装饰器之类的东西,但具有额外的功能。

标签: typescriptdecorator

解决方案


推荐阅读