MST

星途 面试题库

面试题:TypeScript方法装饰器的元编程与AOP

在TypeScript中,基于方法装饰器实现一个面向切面编程(AOP)的功能,用于对类中的多个方法进行权限验证。假设存在一个权限验证函数`checkPermission`,它接受一个权限字符串作为参数并返回布尔值。请编写一个方法装饰器,该装饰器能接受一个权限字符串作为参数,在被装饰的方法执行前调用`checkPermission`函数进行权限验证,如果验证不通过则抛出异常。同时,需要考虑如何通过装饰器元数据来存储权限相关信息,并且能够在运行时动态修改某个类方法的权限设置。
17.5万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试
  1. 定义权限验证函数
    function checkPermission(permission: string): boolean {
        // 这里假设一个简单的逻辑,实际应根据业务需求实现
        const allowedPermissions = ['admin', 'user:read'];
        return allowedPermissions.includes(permission);
    }
    
  2. 定义方法装饰器
    function requirePermission(permission: string) {
        return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
            const originalMethod = descriptor.value;
            descriptor.value = function (...args: any[]) {
                if (!checkPermission(permission)) {
                    throw new Error('权限不足');
                }
                return originalMethod.apply(this, args);
            };
            Reflect.defineMetadata('permission', permission, target, propertyKey);
            return descriptor;
        };
    }
    
  3. 使用装饰器并动态修改权限设置
    class MyClass {
        @requirePermission('admin')
        adminMethod() {
            console.log('这是管理员方法');
        }
        @requirePermission('user:read')
        userReadMethod() {
            console.log('这是用户可读方法');
        }
    }
    const myInstance = new MyClass();
    // 动态修改权限设置
    function updatePermission(target: any, methodName: string, newPermission: string) {
        Reflect.defineMetadata('permission', newPermission, target, methodName);
    }
    updatePermission(MyClass.prototype, 'adminMethod', 'user:write');
    try {
        myInstance.adminMethod();
    } catch (error) {
        console.error(error.message);
    }
    

以上代码中:

  • 首先定义了checkPermission函数,用于模拟权限验证逻辑。
  • 接着定义了requirePermission装饰器,它接受一个权限字符串参数,在被装饰方法执行前调用checkPermission进行验证,并通过Reflect.defineMetadata存储权限相关信息。
  • 最后定义了updatePermission函数,用于动态修改某个类方法的权限设置。在类的实例化后,可以调用该函数修改权限并尝试执行方法,根据权限验证结果进行相应处理。