MST

星途 面试题库

面试题:TypeScript装饰器的参数传递与元数据应用

在TypeScript中,如何在装饰器中传递参数?请以方法装饰器为例,实现一个可以接收参数的方法装饰器,用于记录方法调用的次数并存储在元数据中,同时说明元数据在这个场景中的作用和使用方式。
26.2万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试

在TypeScript中,要在装饰器中传递参数,需要使用一个外层函数来接收参数,并返回真正的装饰器函数。以下是以方法装饰器为例,实现一个可以接收参数的方法装饰器,用于记录方法调用的次数并存储在元数据中:

  1. 引入必要的库: 为了使用元数据,需要引入reflect - metadata库。在项目中安装并导入:

    npm install reflect - metadata
    

    在代码中导入:

    import "reflect - metadata";
    
  2. 实现装饰器

    const callCountMetadataKey = Symbol("callCount");
    
    function callLogger(namespace: string) {
        return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
            const originalMethod = descriptor.value;
            descriptor.value = function (...args: any[]) {
                let callCount = Reflect.getMetadata(callCountMetadataKey, target, propertyKey) || 0;
                callCount++;
                Reflect.defineMetadata(callCountMetadataKey, callCount, target, propertyKey);
                console.log(`${namespace}: Method ${propertyKey} called ${callCount} times`);
                return originalMethod.apply(this, args);
            };
            return descriptor;
        };
    }
    
    class MyClass {
        @callLogger('MyClassNamespace')
        myMethod() {
            console.log('Method executed');
        }
    }
    
    const myObj = new MyClass();
    myObj.myMethod();
    myObj.myMethod();
    
  3. 元数据在这个场景中的作用和使用方式

    • 作用:元数据在这个场景中用于存储方法的调用次数。它提供了一种将额外信息附加到类、方法或属性上的机制,而不需要在目标对象的结构中直接添加这些信息,从而保持代码的整洁和低耦合。
    • 使用方式:通过Reflect.getMetadata方法获取元数据,通过Reflect.defineMetadata方法定义元数据。在上述例子中,Reflect.getMetadata(callCountMetadataKey, target, propertyKey)获取特定方法的调用次数,Reflect.defineMetadata(callCountMetadataKey, callCount, target, propertyKey)更新调用次数并重新存储到元数据中。