返回相同函数类型的通用 memoize 函数
Generic memoize function returning the same function type
我正在尝试编写一个记忆函数,它将一个函数作为参数,return一个类似的记忆函数。
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");
});
问题是如果我只是 return g
,exp 的签名变成 (...args: any[]) => RexExp
如果我试图强制 g 成为 T,那么 ts
抱怨 g 不可分配给 T
.
有没有办法让 "force" g
与 f
相同类型,以便 exp
具有完全相同类型的函数传递给memoize
?
这似乎有效:
function memoize<R, T extends (...args: any[]) => 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 as T;
}
const exp = memoize((text: string) => {
return new RegExp(text.replace(/[^a-zA-Z0-9\s]/g, ".").replace(/\s+/g, "\s+"), "ig");
});
我正在尝试编写一个记忆函数,它将一个函数作为参数,return一个类似的记忆函数。
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");
});
问题是如果我只是 return g
,exp 的签名变成 (...args: any[]) => RexExp
如果我试图强制 g 成为 T,那么 ts
抱怨 g 不可分配给 T
.
有没有办法让 "force" g
与 f
相同类型,以便 exp
具有完全相同类型的函数传递给memoize
?
这似乎有效:
function memoize<R, T extends (...args: any[]) => 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 as T;
}
const exp = memoize((text: string) => {
return new RegExp(text.replace(/[^a-zA-Z0-9\s]/g, ".").replace(/\s+/g, "\s+"), "ig");
});