Typescript中的Typesafe包装函数

Typescript中的Typesafe包装函数,typescript,types,Typescript,Types,我想将我的服务方法包装在一个cachify方法中,该方法在查询数据库之前检查缓存。但是,我无法保留包装函数的类型声明 包装cachify函数如下所示: //cache.ts const cachify=async(fn,args):Promise=>{ const key=constructHashKey(args) const cachedEntry=get(键) 如有需要(cachedEntry){ 回信寄存处 }否则{ const entry=await fn(…args) 放置(键、条目

我想将我的服务方法包装在一个
cachify
方法中,该方法在查询数据库之前检查缓存。但是,我无法保留包装函数的类型声明

包装
cachify
函数如下所示:

//cache.ts
const cachify=async(fn,args):Promise=>{
const key=constructHashKey(args)
const cachedEntry=get(键)
如有需要(cachedEntry){
回信寄存处
}否则{
const entry=await fn(…args)
放置(键、条目)
返回条目
}
}
以下是包装函数的使用示例:

//userService.ts
const getUserProfilePhotoUrl=async(id:string,size:string):Promise=>{
返回cachify(fetchPhotoUrl[
身份证件
大小
])
}
fetchPhotoUrl
函数具有签名
(id:string,size:string):Promise


但是,如果我在数组
[id,size]
中添加一些任意参数,则不会出现任何类型错误。如何让Typescript意识到这一点?

您可以获得所需的行为,只需向函数添加一些类型参数,即可捕获传入的实际参数类型

const cachify = async <T, A extends [any] | any[]>(fn: (...a: A) => Promise<T>, args: A): Promise<T> => {
    const key = constructHashKey(args)
    const cachedEntry = get(key)

    if (cachedEntry) {
        return cachedEntry
    } else {
        const entry = await fn(...args)
        put(key, entry)
        return entry
    }

}

declare function fetchPhotoUrl(id: string, size: string): Promise<string>;
const getUserProfilePhotoUrl = async (id: string, size: string): Promise<string> => {
    return cachify(fetchPhotoUrl, [
        id,
        size
    ])
}
constcachify=async(fn:(…a:a)=>Promise,args:a):Promise=>{
const key=constructHashKey(args)
const cachedEntry=get(键)
如有需要(cachedEntry){
回信寄存处
}否则{
const entry=await fn(…args)
放置(键、条目)
返回条目
}
}
声明函数fetchPhotoUrl(id:string,size:string):Promise;
const getUserProfilePhotoUrl=async(id:string,size:string):Promise=>{
返回cachify(fetchPhotoUrl[
身份证件
大小
])
}
如果您所要做的只是将参数沿路径转发,则此版本可能会使事情变得更简单:

const cachify = <T, A extends [any] | any[]>(fn: (...a: A) => Promise<T>): ((...args: A) => Promise<T>) => {
    return async function (...args: A) {
        const key = constructHashKey(args)
        const cachedEntry = get(key)

        if (cachedEntry) {
            return cachedEntry
        } else {
            const entry = await fn(...args)
            put(key, entry)
            return entry
        }
    }
}

declare function fetchPhotoUrl(id: string, size: string): Promise<string>;
const getUserProfilePhotoUrl = cachify(fetchPhotoUrl)

getUserProfilePhotoUrl("id", "");
constcachify=(fn:(…a:a)=>承诺):((…args:a)=>承诺)=>{
返回异步函数(…参数:A){
const key=constructHashKey(args)
const cachedEntry=get(键)
如有需要(cachedEntry){
回信寄存处
}否则{
const entry=await fn(…args)
放置(键、条目)
返回条目
}
}
}
声明函数fetchPhotoUrl(id:string,size:string):Promise;
const getUserProfilePhotoUrl=cachify(fetchPhotoUrl)
getUserProfilePhotoUrl(“id”,即“”);
getUserProfilePhotoUrl
是完全类型安全的,如果您将鼠标悬停在函数上,而不是在实际代码完成时,则会得到参数名称的工具提示(这应该在将来得到修复)