Skip to content

RedisClientType not compatible across @redis/client versions #2556

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

Open
marwankhalili opened this issue Jul 3, 2023 · 3 comments
Open

RedisClientType not compatible across @redis/client versions #2556

marwankhalili opened this issue Jul 3, 2023 · 3 comments
Labels

Comments

@marwankhalili
Copy link

marwankhalili commented Jul 3, 2023

Description

Hi!

I'm trying to write a utility package for my microservices. Part of the abstraction is related to data stored in Redis‚ so I thought my utility package could reuse the microservice's client connection:

// Utility package - Installs redis as peerDependency
import type { RedisClientType } from "redis";

async function foo(redisClient: RedisClientType) {
  // Use redis client provided by the microservice
}

This utility package worked fine in one microservice, but caused a TypeScript error in another. I noticed the problem occurs when the internal @redis/client version differs between the utility package and the microservice.

Minimal reproducible example:

import type { RedisClientType as ClientA } from "@redis/client-a"; // @redis/[email protected]
import type { RedisClientType as ClientB } from "@redis/client-b"; // @redis/[email protected]

let clientA: ClientA;
let clientB: ClientB;

clientA = clientB; // TypeScript error:  Property '#private' is missing in type 'RedisClient<Record<string, never>, Record<string, never>, Record<string, never>> & WithCommands & WithModules<Record<string, never>> & WithFunctions<...> & WithScripts<...>' but required in type 'RedisClient<Record<string, never>, Record<string, never>, Record<string, never>>'.ts(2322)

package.json:

{
  "dependencies": {
    "@redis/client-a": "npm:@redis/[email protected]",
    "@redis/client-b": "npm:@redis/[email protected]",
    "typescript": "5.1.6"
  }
}

The TypeScript compatibility issue is partially due to the "private" class fields in the declaration files (see microsoft/TypeScript#18499) but also due to the unique symbol used in CommandOptions<T>. The example above only works if I remove both from the declaration files of @redis/client.

Node Redis Version

4.6.6

@marwankhalili marwankhalili changed the title RedisClientType not compatible if @tambur/client version differs RedisClientType not compatible if @redis/client version differs Jul 3, 2023
@leibale
Copy link
Contributor

leibale commented Jul 5, 2023

We are changing the command options API in v5, which removes the CommanOptions<T> type, but anyway, just move the @redis/client from dependencies to peerDependencies in your utility project, and don't lock it to a specific version (this way you'll be able to install the utility package + whatever version of @redis/client you need).

@marwankhalili
Copy link
Author

Cool I hope this can be resolved in v5!

I tried the peerDependencies-route initially (first code example) but the problem is that I'm working on a monorepo. Relying on @redis/client being hoisted won't work since various versions of the library is used across services.

I published an example repository to illustrate this: https://github.com/marwankhalili/redis-utility-example

packages/service-a installs [email protected] -> @redis/[email protected]
packages/service-b installs [email protected] -> @redis/[email protected]

@marwankhalili marwankhalili changed the title RedisClientType not compatible if @redis/client version differs RedisClientType not compatible across @redis/client versions Jul 5, 2023
@marwankhalili
Copy link
Author

Rethinking this, the root issue might be that redis has specified exact versions of internal @redis libraries:

node-redis/package.json

Lines 25 to 32 in a7d5bc7

"dependencies": {
"@redis/bloom": "1.2.0",
"@redis/client": "1.5.8",
"@redis/graph": "1.1.0",
"@redis/json": "1.0.4",
"@redis/search": "1.1.3",
"@redis/time-series": "1.0.4"
},

I believe this issue could be resolved if the caret (^) semver range specifier was used instead, but perhaps there's a reason why that isn't being used?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants