You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript中能否在方法装饰器声明中访问方法参数?

TypeScript中能否在方法装饰器声明中访问方法参数?

嘿,这个问题问到点子上了!我来给你拆解清楚~

首先得明确一个关键时间点:装饰器是在类的定义阶段就执行的,而方法的参数只有在方法被调用的时候才会传入。所以你直接在CacheData(mapKey: string)这个外层装饰器函数里想去拿方法参数,根本行不通——这时候方法还没被调用呢,哪来的参数呀😅

不过别担心,结合你用RxJS做缓存的场景,我们可以调整装饰器的逻辑,在方法被调用的时候去获取参数生成缓存key,这完全是可行的!

给你看看修改后的装饰器写法,适配你的需求:

// 先模拟一个缓存存储,你可以换成实际的缓存实现
const cache = new Map<string, any>();

function CacheData(defaultKey?: string) {
    return function(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
        // 保存原方法的引用
        const originalMethod = descriptor.value;
        
        // 替换原方法,在调用时获取参数
        descriptor.value = function(...args: any[]) {
            // 这里的args就是方法调用时传入的所有参数!
            // 可以根据参数生成缓存key,比如用第一个参数,或者拼接所有参数
            const cacheKey = defaultKey || args.map(arg => 
                typeof arg === 'object' ? JSON.stringify(arg) : arg
            ).join(':');
            
            // 先查缓存,有就直接返回
            if (cache.has(cacheKey)) {
                console.log(`从缓存获取数据:${cacheKey}`);
                return of(cache.get(cacheKey));
            }
            
            // 没有缓存就调用原方法,并存入缓存
            return originalMethod.apply(this, args).pipe(
                tap(data => {
                    console.log(`缓存数据:${cacheKey}`);
                    cache.set(cacheKey, data);
                })
            );
        };
        
        return descriptor;
    };
}

然后你可以这样用这个装饰器:

class ApiService {
    constructor(private http: HttpClient) {}

    // 用方法的id参数作为缓存key
    @CacheData()
    fetchUser(id: string): Observable<User> {
        return this.http.get<User>(`/api/users/${id}`);
    }

    // 用默认key + 参数拼接当缓存key
    @CacheData('product-list')
    fetchProducts(category: string, page: number): Observable<Product[]> {
        return this.http.get<Product[]>(`/api/products?category=${category}&page=${page}`);
    }
}

这里有几个要注意的小细节:

  • 替换原方法时要用普通函数(别用箭头函数),这样this才能正确指向类的实例,不然原方法里的this.http会报错。
  • 如果参数是复杂对象,直接转字符串可能会有问题,用JSON.stringify()序列化是个办法,但要注意对象有没有循环引用,或者可以自己实现更高效的序列化方式。
  • 你可以灵活控制key的生成逻辑,比如只取某几个参数,或者给参数加前缀,完全根据你的缓存需求来。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 13:43:16