面试题答案
一键面试- 实现装饰器:
import 'reflect-metadata';
// 定义装饰器
function checkPermissions(allowedRoles: string[]) {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
// 这里假设可以通过某种方式获取当前用户的角色,比如从上下文或者JWT中解析
const currentUserRole = 'admin'; // 示例角色
if (allowedRoles.includes(currentUserRole)) {
return originalMethod.apply(this, args);
} else {
throw new Error('Permission denied');
}
};
return descriptor;
};
}
- 使用反射获取装饰器参数及元数据:
class MyClass {
@checkPermissions(['admin', 'editor'])
myMethod() {
console.log('This is my method');
}
}
// 获取装饰器参数
const metadataKey = Symbol('allowedRoles');
Reflect.defineMetadata(metadataKey, ['admin', 'editor'], MyClass.prototype,'myMethod');
const allowedRoles = Reflect.getMetadata(metadataKey, MyClass.prototype,'myMethod');
console.log(allowedRoles);
// 调用方法
const myObj = new MyClass();
myObj.myMethod();
- 说明:
- 首先,引入
reflect - metadata
库,这是在TypeScript中使用反射功能的基础。 checkPermissions
装饰器接收一个允许角色的字符串数组作为参数,并返回一个函数。这个返回的函数会在目标方法定义时被调用,它修改了目标方法的描述符,在原方法执行前检查当前用户角色是否在允许列表中。- 在类的定义中,使用
@checkPermissions
装饰器来装饰myMethod
方法。 - 通过
Reflect.defineMetadata
方法来定义元数据,将允许的角色数组与目标方法关联起来。然后使用Reflect.getMetadata
方法来获取这些元数据。这样就可以在运行时获取到装饰器的参数。
- 首先,引入
注意,在实际应用中,获取当前用户角色的逻辑应该是从真实的认证和授权机制中获取,而不是像示例中简单硬编码。