-
Notifications
You must be signed in to change notification settings - Fork 1.9k
RedisClientType hard to use with createClient #1865
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
In case you want to ignore modules and scripts,
I guess my comment should be added to the docs somewhere, I'll leave this issue open for now |
Thanks! Would it then be an idea to set these generic parameters to |
@leibale Could you provide an example how to use a typed client with scripts? What works for me without defining scripts:
However, once I add a script, I get a types are incompatible error.
|
import { createClient, defineScript, RedisModules, RedisScripts, RedisClientType } from '@node-redis/client';
interface ClientOptions<
M extends RedisModules,
S extends RedisScripts
> {
port: number;
host: string;
pw: string;
modules?: M;
scripts?: S;
}
function clientFactory<
M extends RedisModules,
S extends RedisScripts
>(options: ClientOptions<M, S>): RedisClientType<M, S> {
return createClient({
socket: {
port: options.port,
host: options.host
},
password: options.pw,
modules: options.modules,
scripts: options.scripts
});
}
const client = clientFactory({
port: 6379,
host: 'host',
pw: 'pw',
scripts: {
add: defineScript({
NUMBER_OF_KEYS: 1,
SCRIPT: 'local val = redis.pcall("GET", KEYS[1]);' + 'return val + ARGV[1];',
transformArguments(key: string, toAdd: number): Array<string> {
return [key, toAdd.toString()]
},
transformReply(reply: number): number {
return reply
},
})
}
});
client.add('key', 1);
// ^? |
Hm...thanks for the example, but what I really need is a factory that returns the type of the configured client; not the generic one. My application will use the same client everywhere, so I need a type to pass around the configured client. For example say I'd like to pass my client to a function: // how to best define the MyClient type here?
function doAdd(client: MyClient) {
client.add('key', 1);
} Now adding on to your example, the following works, but requires a lot of declaration: export type MyClient = RedisClientType<RedisModules, {
add: {
NUMBER_OF_KEYS: number;
SCRIPT: string;
transformArguments(this: void, key: string, toAdd: number): Array<string>;
transformReply(this: void, reply: number): number;
} &
{
SHA1: string;
}
}> @leibale Would it be feasible to export the This would make the declaration (and therefore using) this library much easier: export interface ConfiguredRedisScripts extends RedisScripts {
add: RedisScript
}
export type MyClient = RedisClientType<RedisModules, ConfiguredRedisScripts>
function doAdd(client: MyClient) {
client.add('key', 1);
} |
import { createClient } from '@node-redis/client';
export const client = createClient({
modules: {
// ...
},
scripts: {
// ...
}
});
export type CustomRedisClient = typeof client;
const duplicate = client.duplicate(); import { createClient } from '@node-redis/client';
const modules = {
// ...
};
const scripts = {
// ...
};
export type CustomRedisClient = RedisClientType<typeof modules, typeof scripts>;
export function clientFactory(): CustomRedisClient {
return createClient({
modules,
scripts
});
} |
@leibale thanks for adding the defaults to the RedisClientType params. However, now the following code import redis, { RedisClientType } from 'redis'
function createRedisClient(): Promise<RedisClientType> {
const client = redis.createClient(...redisConfig...)
await client.connect()
return client
} fails with an error of the type
|
@tobiasdiez #1984 should fix it |
Thanks! I haven't had a chance to try it, but codewise it looks good to me. |
I hate to bother you again, but the code from above (#1865 (comment)) is still not working and now fails with
The issue here is that the script type returned by |
@leibale any update on this, it's not working since v4.1.0, #1865 (comment) |
@leibale can this issue please be reopened, it is still not working as reported above #1865 (comment). Thanks! |
@tobiasdiez the default is that there are no scripts, why is that a problem? |
The issue is that if you do use scripts, then you need to specify the type of the scripts everywhere. Instead of "no scripts", something like "generic scripts" would be helpful. The goal is to make the following code work
Currently, one need to use |
Thanks but this is not really what I need. My requirements (and I believe many others are in a similar position) are as follows:
In both instances, I'm not really able to easily type the redis client. I could pass down the generics as you suggest with your The following code works import redis, { RedisClientType } from 'redis'
type RedisClient = RedisClientType<redis.RedisModules, redis.RedisFunctions, redis.RedisScripts>
async function createRedisClient(): Promise<RedisClient> {
const client = redis.createClient()
await client.connect()
return client
} My suggestion is that the generics of |
|
function store<M, F, S>(client: RedisClientType<M, F, S>, value: string) {
// use client here...
} This gets ugly quickly. |
regarding 3 - you can use the typescript const client = createClient({
// ...
});
type MyRedisClient = typeof client; |
Yes, but only if you don't use a factory method to create the client, since then |
Just came here to say that all of this seems far too hard and worthy of a breaking change to the type definitions. After struggling with this for far too long I just put |
This worked for me:
|
Thanks @thatcort , I my case just |
I've encountered the same typing issue. Fix:
import { createClient, RedisClientType } from 'redis';
const client: RedisClientType = createClient({ url: '' }); |
The RedisClientType has two generic parameters that make it hard to use to signify the return type of
createClient
. In particular, the first argumentmodules
in the declaration ofcreateClient
is a local variable that is not exported and thus cannot be easily reused in one's own code.Maybe it's already enough to provide sufficiently general defaults for the generic arguments. If I'm not mistaken these parameters control more the configuration of the client and don't really influence the typing of the "normal" methods; so they are not that important for an user of a factory method.
Below is a similar observation from #1673.
The
RedisClientType
exported since 4.0.1 still does not work for me. Could not figure out how to make the exportedRedisClientType
,RedisClientOptions
and the type returned bycreateClient
compatible. Here is an example that illustrates the issue.The following does not compile unless someone knows how to type
RedisClientOptions
correctly (refer to the code sandbox link above).Instead, I am doing this for now:
Originally posted by @tbinna in #1673 (comment)
The text was updated successfully, but these errors were encountered: