redis / node-redis

Redis Node.js client
https://redis.js.org/
MIT License
16.96k stars 1.89k forks source link

typescript interface request #1732

Closed huineng closed 3 years ago

huineng commented 3 years ago

latest version 4

i declare my redisclient upfront but i have to import the redisclienttype seperately

import { createClient } from 'redis';
import { RedisClientType } from '@node-redis/client/dist/lib/client';

export class Redis {
    public redisClient!: RedisClientType<any>;

   ......

   this.redisClient = createClient({
                url: this.credentials.uri,
                legacyMode: true,
                socket: {
                    tls: true,
                    ca,
                    reconnectStrategy: redisRetryStrategy,
                },
            });

can you re-export it ? so that i don't have to install @node-redis separately

Module '"redis"' declares 'RedisClientType' locally, but it is not exported.ts(2459)
import { RedisScripts } from '@node-redis/client/dist/lib/commands';
import { RedisClientOptions, RedisClientType } from '@node-redis/client/dist/lib/client';
import { RedisClusterOptions, RedisClusterType } from '@node-redis/client/dist/lib/cluster';
export * from '@node-redis/client';
export * from '@node-redis/json';
export * from '@node-redis/search';

thanks

leibale commented 3 years ago

RedisClient and RedisCluster can be extended with Redis modules & Lua Scripts, therefore using RedisClientType and RedisClusterType directly is not a good idea (because you'll need to pass in modules and scripts). I would use the typeof operator whenever possible to avoid that:

import { createClient } from '@node-redis/client';

export const client = createClient();

export type RedisClientType = typeof client;
vpontis commented 3 years ago

Hmm, I'm not sure if it's related but I'm getting this error while trying to upgrade to 4.0

src/utils/cache-utils.ts:8:14 - error TS2742: The inferred type of 'cacheClient' cannot be named without a reference to '.pnpm/@node-redis+search@1.0.0_@node-redis+client@1.0.0/node_modules/@node-redis/search/dist/commands/CREATE'. This is likely not portable. A type annotation is necessary.

8 export const cacheClient = createClient({ url: config.redisUrl });
               ~~~~~~~~~~~

src/utils/cache-utils.ts:8:14 - error TS2742: The inferred type of 'cacheClient' cannot be named without a reference to '.pnpm/@node-redis+search@1.0.0_@node-redis+client@1.0.0/node_modules/@node-redis/search/dist/commands/DICTADD'. This is likely not portable. A type annotation is necessary.

8 export const cacheClient = createClient({ url: config.redisUrl });
               ~~~~~~~~~~~

src/utils/cache-utils.ts:8:14 - error TS2742: The inferred type of 'cacheClient' cannot be named without a reference to '.pnpm/@node-redis+search@1.0.0_@node-redis+client@1.0.0/node_modules/@node-redis/search/dist/commands/DICTDEL'. This is likely not portable. A type annotation is necessary.

8 export const cacheClient = createClient({ url: config.redisUrl });
               ~~~~~~~~~~~

src/utils/cache-utils.ts:8:14 - error TS2742: The inferred type of 'cacheClient' cannot be named without a reference to '.pnpm/@node-redis+search@1.0.0_@node-redis+client@1.0.0/node_modules/@node-redis/search/dist/commands/DICTDUMP'. This is likely not portable. A type annotation is necessary.

8 export const cacheClient = createClient({ url: config.redisUrl });
               ~~~~~~~~~~~

src/utils/cache-utils.ts:8:14 - error TS2742: The inferred type of 'cacheClient' cannot be named without a reference to '.pnpm/@node-redis+search@1.0.0_@node-redis+client@1.0.0/node_modules/@node-redis/search/dist/commands/DROPINDEX'. This is likely not portable. A type annotation is necessary.

8 export const cacheClient = createClient({ url: config.redisUrl });
               ~~~~~~~~~~~

And my code is:

import { createClient } from "redis";

export const cacheClient = createClient({ url: config.redisUrl });

I'm not sure how to fix it. I've done a decent amount of Typescript work and I haven't run into this particular issue before.

tobiasdiez commented 3 years ago
import { createClient } from '@node-redis/client';

export const client = createClient();

export type RedisClientType = typeof client;

That works in some cases, but not as function return types (except if I'm missing something)

import { createClient } from '@node-redis/client';
function createRedis(): ??? {
   return createClient(...)
}
huineng commented 3 years ago

well, the answer given to me using const client = createClient ... is working .. on the other side I'm not completely understanding why re exporting a type or interface is a big problem

import { RedisScripts } from '@node-redis/client/dist/lib/commands';
import { RedisClientOptions, RedisClientType } from '@node-redis/client/dist/lib/client';
import { RedisClusterOptions, RedisClusterType } from '@node-redis/client/dist/lib/cluster';

export { RedisClientType };   <---

export * from '@node-redis/client';
export * from '@node-redis/json';
export * from '@node-redis/search';
leibale commented 3 years ago

The advantage of using typeof is that if someone will extend the client in the future, he'll not need to change the RedisClientType generics everywhere...

But I understand that in some cases using the generic type does make sense, and there's already a PR that implements exactly that. I'll merge it soon.

leibale commented 3 years ago

Duplicate of #1673

rodion-arr commented 3 years ago

Probably this may be used as workaround:

type RedisClient = ReturnType<typeof createClient>;