I have an arrow function, it is used for cached queries. It accepts cache key and a callback function with it's arguments. At first this function looks up in Redis with the specified key, and if there is no cache by that key - it executes the callback.
Everything works, but I don't like the way how my declaration looks like: it's unsafe (you can pass argument of wrong type), and on the other hand I have a disabled linter warning. So here is my code (only the relevant part remaining):
import { RedisClient } from './../redis/redisClient';
export type CachedQueryPromiseResult<T> = { result?: T, error?: object };
export type CachedQueryPromise<T> = Promise<CachedQueryPromiseResult<T>>;
export const cachedDbQuery = async <T,>(
opts: { cacheKey: string, ttlSec: number, redis: RedisClient },
callback: (...cbArgs: any) => Promise<T>,
...args: any
): 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;
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
const result = await callback(...args);
if (result) {
await opts.redis.impl.setex(opts.cacheKey, opts.ttlSec, JSON.stringify(result));
response.result = result;
}
return response;
};
How can I declare this callback
? Now it accepts any, but I would like it to deduct the required arguments with the types. It is not safe now.
cachedDbQuery({ redis: redisClient, cacheKey: 'TESTAR', ttlSec: 120 }, vkuClient.getLicenseInfo.bind(vkuClient), identificator)
getLicenseInfo
accepts string, but with the current implementation I can pass any type to it.
What could you suggest?
CodePudding user response:
Add another generic parameter, as TS will be able to infer this one as well:
export const cachedDbQuery = async <T, A extends ReadonlyArray<unknown>>(
opts: { cacheKey: string, ttlSec: number, redis: RedisClient },
callback: (...cbArgs: A) => Promise<T>,
...args: A
): CachedQueryPromise<T> => {
However, since this one represents the arguments, it must have a constraint of an array.