【发布时间】:2017-04-13 02:28:16
【问题描述】:
我正在尝试编写一个 memoize 函数,它接受一个函数作为参数并返回一个相似的 memoized 函数。
function memoize<T extends Function, R>(f: T): T {
const memory = new Map<string, R>();
const g = (...args: any[]) => {
if (!memory.get(args.join())) { memory.set(args.join(), f(...args)); }
return memory.get(args.join());
};
return g; // g as T => [ts] Type '(...args: any[]) => R' cannot be converted to type 'T'.
}
// const exp: (...args: any[]) => RegExp
const exp = memoize<(text: string) => RegExp, RegExp>((text: string) => {
return new RegExp(text.replace(/[^a-zA-Z0-9\s]/g, ".").replace(/\s+/g, "\\s+"), "ig");
});
问题是,如果我只返回 g ,则 exp 的签名变为 (...args: any[]) => RexExp 并且如果我试图强制 g 为 T,那么 ts 抱怨 g 不能分配给 T。
有没有办法“强制”g 与 f 相同类型,以便 exp 将完全相同类型的函数传递给 memoize?
【问题讨论】:
-
args.join()不适合作为键:您对获取对象的函数有问题,因为例如,[{}].join()和[{foo: 'bar'}].join()返回相同的值:"[object Object]"。仅使用args作为映射键并没有更好,因为映射使用严格相等,因此“非严格相等”值将被多次记忆。 -
@artem 感谢 cmets。你是对的,那不是一把好钥匙。看起来使用地图构建树会是更好的解决方案。