MST

星途 面试题库

面试题:TypeScript类装饰器@decorator在复杂场景下的应用

假设你正在开发一个大型的前端应用,其中有多个具有权限控制的类。请使用TypeScript类装饰器@authorize,实现一个权限控制机制,使得只有具有特定权限的用户才能访问类中的某些方法。装饰器需要能够根据不同的方法配置不同的权限要求,并且要考虑如何与现有的身份验证系统集成。请详细描述实现思路并给出关键代码示例。
19.8万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 定义权限枚举:首先定义一个枚举类型,用于表示不同的权限。
  2. 编写装饰器函数:创建一个@authorize装饰器,该装饰器接收一个权限数组作为参数。在装饰器内部,它会遍历类的原型方法,并将原方法替换为一个新的方法,新方法在调用原方法之前会检查用户是否具有所需权限。
  3. 集成身份验证系统:假设现有的身份验证系统提供了一个函数(例如getCurrentUserPermissions)来获取当前用户的权限。在装饰器创建的新方法中调用这个函数,以检查权限。

关键代码示例

// 1. 定义权限枚举
enum Permission {
    Read = 'read',
    Write = 'write',
    Admin = 'admin'
}

// 2. 编写装饰器函数
function authorize(requiredPermissions: Permission[]) {
    return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
        const originalMethod = descriptor.value;
        descriptor.value = function (...args: any[]) {
            // 假设这是从现有身份验证系统获取当前用户权限的函数
            const currentUserPermissions = getCurrentUserPermissions();
            const hasPermission = requiredPermissions.some(permission => currentUserPermissions.includes(permission));
            if (!hasPermission) {
                throw new Error('没有足够的权限');
            }
            return originalMethod.apply(this, args);
        };
        return descriptor;
    };
}

// 模拟获取当前用户权限的函数
function getCurrentUserPermissions(): Permission[] {
    // 这里可以根据实际身份验证系统逻辑返回权限
    return [Permission.Read];
}

// 使用装饰器的类
class MyClass {
    @authorize([Permission.Read])
    readData() {
        console.log('读取数据');
    }

    @authorize([Permission.Write])
    writeData() {
        console.log('写入数据');
    }

    @authorize([Permission.Admin])
    adminOperation() {
        console.log('执行管理员操作');
    }
}

// 测试
const myInstance = new MyClass();
myInstance.readData();
// myInstance.writeData(); // 这行代码会抛出没有足够权限的错误
// myInstance.adminOperation(); // 这行代码会抛出没有足够权限的错误