diff --git a/packages/client/lib/client/index.ts b/packages/client/lib/client/index.ts index cf5763357a..cc7df1b5e4 100644 --- a/packages/client/lib/client/index.ts +++ b/packages/client/lib/client/index.ts @@ -10,7 +10,7 @@ import { TcpSocketConnectOpts } from 'node:net'; import { PUBSUB_TYPE, PubSubType, PubSubListener, PubSubTypeListeners, ChannelListeners } from './pub-sub'; import { Command, CommandSignature, TypeMapping, CommanderConfig, RedisFunction, RedisFunctions, RedisModules, RedisScript, RedisScripts, ReplyUnion, RespVersions, RedisArgument, ReplyWithTypeMapping, SimpleStringReply, TransformReply, CommandArguments } from '../RESP/types'; import RedisClientMultiCommand, { RedisClientMultiCommandType } from './multi-command'; -import { RedisMultiQueuedCommand } from '../multi-command'; +import { MULTI_MODE, MultiMode, RedisMultiQueuedCommand } from '../multi-command'; import HELLO, { HelloOptions } from '../commands/HELLO'; import { ScanOptions, ScanCommonOptions } from '../commands/SCAN'; import { RedisLegacyClient, RedisLegacyClientType } from './legacy-mode'; @@ -1315,8 +1315,8 @@ export default class RedisClient< return execResult as Array; } - MULTI() { - type Multi = new (...args: ConstructorParameters) => RedisClientMultiCommandType<[], M, F, S, RESP, TYPE_MAPPING>; + MULTI() { + type Multi = new (...args: ConstructorParameters) => RedisClientMultiCommandType; return new ((this as any).Multi as Multi)( this._executeMulti.bind(this), this._executePipeline.bind(this), diff --git a/packages/client/lib/client/multi-command.ts b/packages/client/lib/client/multi-command.ts index a687655b60..fdb958b803 100644 --- a/packages/client/lib/client/multi-command.ts +++ b/packages/client/lib/client/multi-command.ts @@ -1,5 +1,5 @@ import COMMANDS from '../commands'; -import RedisMultiCommand, { MULTI_REPLY, MultiReply, MultiReplyType, RedisMultiQueuedCommand } from '../multi-command'; +import RedisMultiCommand, { MULTI_MODE, MULTI_REPLY, MultiMode, MultiReply, MultiReplyType, RedisMultiQueuedCommand } from '../multi-command'; import { ReplyWithTypeMapping, CommandReply, Command, CommandArguments, CommanderConfig, RedisFunctions, RedisModules, RedisScripts, RespVersions, TransformReply, RedisScript, RedisFunction, TypeMapping } from '../RESP/types'; import { attachConfig, functionArgumentsPrefix, getTransformReply } from '../commander'; import { BasicCommandParser } from './parser'; @@ -13,7 +13,7 @@ type CommandSignature< S extends RedisScripts, RESP extends RespVersions, TYPE_MAPPING extends TypeMapping -> = (...args: Tail>) => RedisClientMultiCommandType< +> = (...args: Tail>) => InternalRedisClientMultiCommandType< [...REPLIES, ReplyWithTypeMapping, TYPE_MAPPING>], M, F, @@ -70,7 +70,7 @@ type WithScripts< [P in keyof S]: CommandSignature; }; -export type RedisClientMultiCommandType< +type InternalRedisClientMultiCommandType< REPLIES extends Array, M extends RedisModules, F extends RedisFunctions, @@ -85,6 +85,19 @@ export type RedisClientMultiCommandType< WithScripts ); +type TypedOrAny = + [Flag] extends [MULTI_MODE['TYPED']] ? T : any; + +export type RedisClientMultiCommandType< + isTyped extends MultiMode, + REPLIES extends Array, + M extends RedisModules, + F extends RedisFunctions, + S extends RedisScripts, + RESP extends RespVersions, + TYPE_MAPPING extends TypeMapping +> = TypedOrAny>; + type ExecuteMulti = (commands: Array, selectedDB?: number) => Promise>; export default class RedisClientMultiCommand { diff --git a/packages/client/lib/client/pool.ts b/packages/client/lib/client/pool.ts index b53bb2c7e6..75aca57a9f 100644 --- a/packages/client/lib/client/pool.ts +++ b/packages/client/lib/client/pool.ts @@ -10,6 +10,7 @@ import RedisClientMultiCommand, { RedisClientMultiCommandType } from './multi-co import { BasicPooledClientSideCache, ClientSideCacheConfig, PooledClientSideCacheProvider } from './cache'; import { BasicCommandParser } from './parser'; import SingleEntryCache from '../single-entry-cache'; +import { MULTI_MODE, MultiMode } from '../multi-command'; export interface RedisPoolOptions { /** @@ -486,8 +487,9 @@ export class RedisClientPool< return this.execute(client => client.sendCommand(args, options)); } - MULTI() { - type Multi = new (...args: ConstructorParameters) => RedisClientMultiCommandType<[], M, F, S, RESP, TYPE_MAPPING>; + + MULTI() { + type Multi = new (...args: ConstructorParameters) => RedisClientMultiCommandType; return new ((this as any).Multi as Multi)( (commands, selectedDB) => this.execute(client => client._executeMulti(commands, selectedDB)), commands => this.execute(client => client._executePipeline(commands)), diff --git a/packages/client/lib/multi-command.ts b/packages/client/lib/multi-command.ts index 3d45a02fb4..bb30fddc29 100644 --- a/packages/client/lib/multi-command.ts +++ b/packages/client/lib/multi-command.ts @@ -6,6 +6,13 @@ export type MULTI_REPLY = { TYPED: 'typed'; }; +export type MULTI_MODE = { + TYPED: 'typed'; + UNTYPED: 'untyped'; +}; + +export type MultiMode = MULTI_MODE[keyof MULTI_MODE]; + export type MultiReply = MULTI_REPLY[keyof MULTI_REPLY]; export type MultiReplyType = T extends MULTI_REPLY['TYPED'] ? REPLIES : Array;