面试题答案
一键面试1. 正确处理参数类型示例
假设我们有一个简单的类和一个装饰器来处理方法:
function logArgs(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log('Arguments:', args);
return originalMethod.apply(this, args);
};
return descriptor;
}
class MyClass {
@logArgs
greet(name: string, age: number) {
return `Hello, ${name}! You are ${age} years old.`;
}
}
const myObj = new MyClass();
console.log(myObj.greet('Alice', 30));
在这个例子中,logArgs
装饰器使用了 ...args: any[]
来接收所有传入 greet
方法的参数,这样可以确保无论 greet
方法有多少个参数,装饰器都能正确处理。
2. 可能出现的错误情况
如果在装饰器中硬编码参数类型,就会出现问题。例如:
function wrongLogArgs(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function (name: string, age: number) {
console.log('Arguments:', name, age);
return originalMethod.apply(this, arguments);
};
return descriptor;
}
class AnotherClass {
@wrongLogArgs
greet(name: string, age: number) {
return `Hello, ${name}! You are ${age} years old.`;
}
}
const anotherObj = new AnotherClass();
// 假设这里我们想添加一个新的参数,比如问候语类型
// 如果使用硬编码的参数类型,就会报错
// anotherObj.greet('Bob', 25, 'Formal');
这里装饰器 wrongLogArgs
硬编码了参数类型为 string
和 number
,如果后续被装饰的方法参数有变化,就会导致类型错误。
3. 解决办法
使用 ...args: any[]
来接收参数,这样可以灵活处理不同数量和类型的参数,就像第一个示例中的 logArgs
装饰器一样。另外,如果需要对参数进行类型检查,可以在装饰器内部使用类型断言或类型保护。例如:
function betterLogArgs(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
if (args.length === 2 && typeof args[0] ==='string' && typeof args[1] === 'number') {
console.log('Arguments:', args);
} else {
console.log('Unexpected argument types or count');
}
return originalMethod.apply(this, args);
};
return descriptor;
}
class YetAnotherClass {
@betterLogArgs
greet(name: string, age: number) {
return `Hello, ${name}! You are ${age} years old.`;
}
}
const yetAnotherObj = new YetAnotherClass();
console.log(yetAnotherObj.greet('Charlie', 22));
这样既可以灵活接收参数,又能在必要时进行类型检查。