面试题答案
一键面试// 定义一个类型别名,用于表示缓存函数的返回值
// 这里的泛型 T 表示原始函数的返回值类型
type CacheResult<T> = {
value: T;
timestamp: number;
};
// 定义一个类型别名,用于表示缓存对象
// 这里的泛型 F 表示原始函数类型,通过 Parameters<F> 获取函数参数类型,ReturnType<F> 获取函数返回值类型
type Cache<F extends (...args: any[]) => any> = {
[key: string]: CacheResult<ReturnType<F>>;
};
// 定义缓存函数,接受一个原始函数作为参数
function createCache<F extends (...args: any[]) => any>(fn: F): (...args: Parameters<F>) => ReturnType<F> {
const cache: Cache<F> = {};
return function (...args: Parameters<F>): ReturnType<F> {
const key = args.toString();
if (cache[key] && Date.now() - cache[key].timestamp < 1000) { // 缓存命中,假设缓存有效期1秒
return cache[key].value;
}
const result = fn.apply(this, args);
cache[key] = {
value: result,
timestamp: Date.now()
};
return result;
};
}
// 示例函数
function add(a: number, b: number): number {
return a + b;
}
const cachedAdd = createCache(add);
console.log(cachedAdd(1, 2)); // 第一次调用,计算并缓存
console.log(cachedAdd(1, 2)); // 第二次调用,命中缓存
类型别名设计解释
CacheResult<T>
:- 这个类型别名用于定义缓存结果的结构。
T
是一个泛型,代表原始函数的返回值类型。 value
属性存储原始函数的返回值。timestamp
属性记录缓存的时间戳,用于判断缓存是否过期。
- 这个类型别名用于定义缓存结果的结构。
Cache<F>
:F
是一个泛型,代表原始函数类型,要求F
是一个接受任意参数并返回任意类型的函数。- 这个类型别名定义了缓存对象的结构,它是一个对象,键是字符串类型(由函数参数生成),值是
CacheResult<ReturnType<F>>
类型,即缓存结果类型,其中ReturnType<F>
提取了原始函数F
的返回值类型。
createCache<F>
:F
同样是代表原始函数类型的泛型。- 该函数接受一个类型为
F
的原始函数fn
作为参数,并返回一个新的函数。 - 返回的新函数接受与原始函数
fn
相同类型的参数(通过Parameters<F>
获取),并返回与原始函数fn
相同类型的返回值(通过ReturnType<F>
获取)。
通过这些类型别名的设计,精确控制了缓存函数的输入输出类型,以及缓存对象的结构,确保了类型安全和代码的可维护性。