如何为缓存查询回调函数推导参数类型?
解决TypeScript缓存查询函数的类型安全问题
当前你实现的cachedDbQuery函数功能正常,但存在类型不安全的问题:回调函数参数和传入的args都用any类型,导致无法校验参数类型匹配,还得禁用@typescript-eslint/no-unsafe-argument警告。要实现回调参数类型的自动推导,只需给函数添加参数类型的泛型约束,具体修改如下:
修改后的完整代码
import { RedisClient } from './../redis/redisClient'; export type CachedQueryPromiseResult<T> = { result?: T, error?: object }; export type CachedQueryPromise<T> = Promise<CachedQueryPromiseResult<T>>; // 添加Args泛型约束回调参数和传入的args类型 export const cachedDbQuery = async <T, Args extends any[]>( opts: { cacheKey: string, ttlSec: number, redis: RedisClient }, callback: (...cbArgs: Args) => Promise<T>, ...args: Args ): CachedQueryPromise<T> => { const response: CachedQueryPromiseResult<T> = {}; const cache = await opts.redis.impl.get(opts.cacheKey); if (cache) { response.result = JSON.parse(cache) as T; return response; } // 现在参数类型安全,可移除lint禁用注释 const result = await callback(...args); if (result) { await opts.redis.impl.setex(opts.cacheKey, opts.ttlSec, JSON.stringify(result)); response.result = result; } return response; };
关键修改说明
- 新增泛型参数
Args extends any[]:用来表示回调函数的参数类型数组,any[]确保它能匹配任意长度的参数列表 - 约束
callback类型为(...cbArgs: Args) => Promise<T>:让回调的参数类型和Args绑定 - 约束
args类型为Args:确保传入的参数和回调要求的参数类型完全一致
调用示例验证
现在调用时,TypeScript会自动推导回调的参数类型:
// 假设vkuClient.getLicenseInfo的类型为(identificator: string) => Promise<LicenseInfo> cachedDbQuery( { redis: redisClient, cacheKey: 'TESTAR', ttlSec: 120 }, vkuClient.getLicenseInfo.bind(vkuClient), identificator // 若identificator不是string类型,TypeScript会直接报错 );
这样不仅解决了类型不安全的问题,还能移除之前的lint禁用注释,完全符合TypeScript的类型校验规则。
内容的提问来源于stack exchange,提问作者Arman Oganesyan
相关产品推荐
相关产品推荐

