1
0
mirror of https://github.com/redis/node-redis.git synced 2025-08-06 02:15:48 +03:00

fix some types

This commit is contained in:
leibale
2021-12-23 17:17:19 -05:00
parent b37038e9dc
commit b97d18b610
10 changed files with 42 additions and 34 deletions

View File

@@ -122,7 +122,11 @@ This pattern works especially well for blocking commands—such as `BLPOP` and `
```typescript ```typescript
import { commandOptions } from 'redis'; import { commandOptions } from 'redis';
const blPopPromise = client.blPop(commandOptions({ isolated: true }), 'key', 0); const blPopPromise = client.blPop(
commandOptions({ isolated: true }),
'key',
0
);
await client.lPush('key', ['1', '2']); await client.lPush('key', ['1', '2']);

View File

@@ -15,7 +15,7 @@ const modules = {
ts: RedisTimeSeries ts: RedisTimeSeries
}; };
export function createClient<S extends RedisScripts = Record<string, never>>( export function createClient<S extends RedisScripts>(
options?: Omit<RedisClientOptions<never, S>, 'modules'> options?: Omit<RedisClientOptions<never, S>, 'modules'>
): RedisClientType<typeof modules, S> { ): RedisClientType<typeof modules, S> {
return _createClient({ return _createClient({
@@ -24,7 +24,7 @@ export function createClient<S extends RedisScripts = Record<string, never>>(
}); });
} }
export function createCluster<S extends RedisScripts = Record<string, never>>( export function createCluster<S extends RedisScripts>(
options: Omit<RedisClusterOptions<never, S>, 'modules'> options: Omit<RedisClusterOptions<never, S>, 'modules'>
): RedisClusterType<typeof modules, S> { ): RedisClusterType<typeof modules, S> {
return _createCluster({ return _createCluster({

View File

@@ -573,8 +573,8 @@ describe('Client', () => {
describe('PubSub', () => { describe('PubSub', () => {
testUtils.testWithClient('should be able to publish and subscribe to messages', async publisher => { testUtils.testWithClient('should be able to publish and subscribe to messages', async publisher => {
function assertStringListener(message: string, channel: string) { function assertStringListener(message: string, channel: string) {
assert.ok(typeof message === 'string'); assert.equal(typeof message, 'string');
assert.ok(typeof channel === 'string'); assert.equal(typeof channel, 'string');
} }
function assertBufferListener(message: Buffer, channel: Buffer) { function assertBufferListener(message: Buffer, channel: Buffer) {

View File

@@ -34,11 +34,13 @@ type ConvertArgumentType<Type, ToType> =
) : ( ) : (
Type extends Set<infer Member> ? Set<ConvertArgumentType<Member, ToType>> : ( Type extends Set<infer Member> ? Set<ConvertArgumentType<Member, ToType>> : (
Type extends Map<infer Key, infer Value> ? Map<Key, ConvertArgumentType<Value, ToType>> : ( Type extends Map<infer Key, infer Value> ? Map<Key, ConvertArgumentType<Value, ToType>> : (
Type extends Array<infer Member> ? Array<ConvertArgumentType<Member, ToType>> : (
Type extends Record<keyof any, any> ? { Type extends Record<keyof any, any> ? {
[Property in keyof Type]: ConvertArgumentType<Type[Property], ToType> [Property in keyof Type]: ConvertArgumentType<Type[Property], ToType>
} : Type } : Type
) )
) )
)
); );
export type RedisClientCommandSignature< export type RedisClientCommandSignature<
@@ -57,21 +59,23 @@ type WithCommands = {
[P in keyof typeof COMMANDS]: RedisClientCommandSignature<(typeof COMMANDS)[P]>; [P in keyof typeof COMMANDS]: RedisClientCommandSignature<(typeof COMMANDS)[P]>;
}; };
export type ExcludeMappedString<S> = string extends S ? never : S;
export type WithModules<M extends RedisModules> = { export type WithModules<M extends RedisModules> = {
[P in keyof M as M[P] extends never ? never : P]: { [P in keyof M as ExcludeMappedString<P>]: {
[C in keyof M[P]]: RedisClientCommandSignature<M[P][C]>; [C in keyof M[P] as ExcludeMappedString<C>]: RedisClientCommandSignature<M[P][C]>;
}; };
}; };
export type WithScripts<S extends RedisScripts> = { export type WithScripts<S extends RedisScripts> = {
[P in keyof S as S[P] extends never ? never : P]: RedisClientCommandSignature<S[P]>; [P in keyof S as ExcludeMappedString<P>]: RedisClientCommandSignature<S[P]>;
}; };
export type RedisClientType<M extends RedisModules = Record<string, never>, S extends RedisScripts = Record<string, never>> = export type RedisClientType<M extends RedisModules, S extends RedisScripts> =
RedisClient<M, S> & WithCommands & WithModules<M> & WithScripts<S>; RedisClient<M, S> & WithCommands & WithModules<M> & WithScripts<S>;
export type InstantiableRedisClient<M extends RedisModules, S extends RedisScripts> = export type InstantiableRedisClient<M extends RedisModules, S extends RedisScripts> =
new (...args: ConstructorParameters<typeof RedisClient>) => RedisClientType<M, S>; new (options?: RedisClientOptions<M, S>) => RedisClientType<M, S>;
export interface ClientCommandOptions extends QueueCommandOptions { export interface ClientCommandOptions extends QueueCommandOptions {
isolated?: boolean; isolated?: boolean;
@@ -85,7 +89,7 @@ export default class RedisClient<M extends RedisModules, S extends RedisScripts>
return commandOptions(options); return commandOptions(options);
} }
static extend<M extends RedisModules = Record<string, never>, S extends RedisScripts = Record<string, never>>(plugins?: RedisPlugins<M, S>): InstantiableRedisClient<M, S> { static extend<M extends RedisModules, S extends RedisScripts>(plugins?: RedisPlugins<M, S>): InstantiableRedisClient<M, S> {
const Client = <any>extendWithModulesAndScripts({ const Client = <any>extendWithModulesAndScripts({
BaseClass: RedisClient, BaseClass: RedisClient,
modules: plugins?.modules, modules: plugins?.modules,
@@ -101,7 +105,7 @@ export default class RedisClient<M extends RedisModules, S extends RedisScripts>
return Client; return Client;
} }
static create<M extends RedisModules = Record<string, never>, S extends RedisScripts = Record<string, never>>(options?: RedisClientOptions<M, S>): RedisClientType<M, S> { static create<M extends RedisModules, S extends RedisScripts>(options?: RedisClientOptions<M, S>): RedisClientType<M, S> {
return new (RedisClient.extend(options))(options); return new (RedisClient.extend(options))(options);
} }

View File

@@ -2,25 +2,26 @@ import COMMANDS from './commands';
import { RedisCommand, RedisCommandArguments, RedisCommandRawReply, RedisModules, RedisPlugins, RedisScript, RedisScripts } from '../commands'; import { RedisCommand, RedisCommandArguments, RedisCommandRawReply, RedisModules, RedisPlugins, RedisScript, RedisScripts } from '../commands';
import RedisMultiCommand, { RedisMultiQueuedCommand } from '../multi-command'; import RedisMultiCommand, { RedisMultiQueuedCommand } from '../multi-command';
import { extendWithCommands, extendWithModulesAndScripts, LegacyCommandArguments, transformLegacyCommandArguments } from '../commander'; import { extendWithCommands, extendWithModulesAndScripts, LegacyCommandArguments, transformLegacyCommandArguments } from '../commander';
import { ExcludeMappedString } from '.';
type RedisClientMultiCommandSignature<C extends RedisCommand, M extends RedisModules, S extends RedisScripts> = type RedisClientMultiCommandSignature<C extends RedisCommand, M extends RedisModules, S extends RedisScripts> =
(...args: Parameters<C['transformArguments']>) => RedisClientMultiCommandType<M, S>; (...args: Parameters<C['transformArguments']>) => RedisClientMultiCommandType<M, S>;
type WithCommands<M extends RedisModules, S extends RedisScripts> = { type WithCommands<M extends RedisModules, S extends RedisScripts> = {
[P in keyof typeof COMMANDS]: RedisClientMultiCommandSignature<(typeof COMMANDS)[P], M, S> [P in keyof typeof COMMANDS]: RedisClientMultiCommandSignature<(typeof COMMANDS)[P], M, S>;
}; };
type WithModules<M extends RedisModules, S extends RedisScripts> = { type WithModules<M extends RedisModules, S extends RedisScripts> = {
[P in keyof M as M[P] extends never ? never : P]: { [P in keyof M as ExcludeMappedString<P>]: {
[C in keyof M[P]]: RedisClientMultiCommandSignature<M[P][C], M, S>; [C in keyof M[P] as ExcludeMappedString<C>]: RedisClientMultiCommandSignature<M[P][C], M, S>;
}; };
}; };
type WithScripts<M extends RedisModules, S extends RedisScripts> = { type WithScripts<M extends RedisModules, S extends RedisScripts> = {
[P in keyof S as S[P] extends never ? never : P]: RedisClientMultiCommandSignature<S[P], M, S> [P in keyof S as ExcludeMappedString<P>]: RedisClientMultiCommandSignature<S[P], M, S>;
}; };
export type RedisClientMultiCommandType<M extends RedisModules = Record<string, never>, S extends RedisScripts = Record<string, never>> = export type RedisClientMultiCommandType<M extends RedisModules, S extends RedisScripts> =
RedisClientMultiCommand & WithCommands<M, S> & WithModules<M, S> & WithScripts<M, S>; RedisClientMultiCommand & WithCommands<M, S> & WithModules<M, S> & WithScripts<M, S>;
export type RedisClientMultiExecutor = (queue: Array<RedisMultiQueuedCommand>, chainId?: symbol) => Promise<Array<RedisCommandRawReply>>; export type RedisClientMultiExecutor = (queue: Array<RedisMultiQueuedCommand>, chainId?: symbol) => Promise<Array<RedisCommandRawReply>>;

View File

@@ -20,10 +20,10 @@ type WithCommands = {
[P in keyof typeof COMMANDS]: RedisClientCommandSignature<(typeof COMMANDS)[P]>; [P in keyof typeof COMMANDS]: RedisClientCommandSignature<(typeof COMMANDS)[P]>;
}; };
export type RedisClusterType<M extends RedisModules = Record<string, never>, S extends RedisScripts = Record<string, never>> = export type RedisClusterType<M extends RedisModules, S extends RedisScripts> =
RedisCluster<M, S> & WithCommands & WithModules<M> & WithScripts<S>; RedisCluster<M, S> & WithCommands & WithModules<M> & WithScripts<S>;
export default class RedisCluster<M extends RedisModules = Record<string, never>, S extends RedisScripts = Record<string, never>> extends EventEmitter { export default class RedisCluster<M extends RedisModules, S extends RedisScripts> extends EventEmitter {
static extractFirstKey(command: RedisCommand, originalArgs: Array<unknown>, redisArgs: RedisCommandArguments): RedisCommandArgument | undefined { static extractFirstKey(command: RedisCommand, originalArgs: Array<unknown>, redisArgs: RedisCommandArguments): RedisCommandArgument | undefined {
if (command.FIRST_KEY_INDEX === undefined) { if (command.FIRST_KEY_INDEX === undefined) {
return undefined; return undefined;
@@ -34,7 +34,7 @@ export default class RedisCluster<M extends RedisModules = Record<string, never>
return command.FIRST_KEY_INDEX(...originalArgs); return command.FIRST_KEY_INDEX(...originalArgs);
} }
static create<M extends RedisModules = Record<string, never>, S extends RedisScripts = Record<string, never>>(options?: RedisClusterOptions<M, S>): RedisClusterType<M, S> { static create<M extends RedisModules, S extends RedisScripts>(options?: RedisClusterOptions<M, S>): RedisClusterType<M, S> {
return new (<any>extendWithModulesAndScripts({ return new (<any>extendWithModulesAndScripts({
BaseClass: RedisCluster, BaseClass: RedisCluster,
modules: options?.modules, modules: options?.modules,

View File

@@ -3,6 +3,7 @@ import { RedisCommand, RedisCommandArgument, RedisCommandArguments, RedisCommand
import RedisMultiCommand, { RedisMultiQueuedCommand } from '../multi-command'; import RedisMultiCommand, { RedisMultiQueuedCommand } from '../multi-command';
import { extendWithCommands, extendWithModulesAndScripts } from '../commander'; import { extendWithCommands, extendWithModulesAndScripts } from '../commander';
import RedisCluster from '.'; import RedisCluster from '.';
import { ExcludeMappedString } from '../client';
type RedisClusterMultiCommandSignature<C extends RedisCommand, M extends RedisModules, S extends RedisScripts> = type RedisClusterMultiCommandSignature<C extends RedisCommand, M extends RedisModules, S extends RedisScripts> =
(...args: Parameters<C['transformArguments']>) => RedisClusterMultiCommandType<M, S>; (...args: Parameters<C['transformArguments']>) => RedisClusterMultiCommandType<M, S>;
@@ -12,16 +13,16 @@ type WithCommands<M extends RedisModules, S extends RedisScripts> = {
}; };
type WithModules<M extends RedisModules, S extends RedisScripts> = { type WithModules<M extends RedisModules, S extends RedisScripts> = {
[P in keyof M as M[P] extends never ? never : P]: { [P in keyof M as ExcludeMappedString<P>]: {
[C in keyof M[P]]: RedisClusterMultiCommandSignature<M[P][C], M, S>; [C in keyof M[P] as ExcludeMappedString<C>]: RedisClusterMultiCommandSignature<M[P][C], M, S>;
}; };
}; };
type WithScripts<M extends RedisModules, S extends RedisScripts> = { type WithScripts<M extends RedisModules, S extends RedisScripts> = {
[P in keyof S as S[P] extends never ? never : P]: RedisClusterMultiCommandSignature<S[P], M, S> [P in keyof S as ExcludeMappedString<P>]: RedisClusterMultiCommandSignature<S[P], M, S>
}; };
export type RedisClusterMultiCommandType<M extends RedisModules = Record<string, never>, S extends RedisScripts = Record<string, never>> = export type RedisClusterMultiCommandType<M extends RedisModules, S extends RedisScripts> =
RedisClusterMultiCommand & WithCommands<M, S> & WithModules<M, S> & WithScripts<M, S>; RedisClusterMultiCommand & WithCommands<M, S> & WithModules<M, S> & WithScripts<M, S>;
export type RedisClusterMultiExecutor = (queue: Array<RedisMultiQueuedCommand>, firstKey?: RedisCommandArgument, chainId?: symbol) => Promise<Array<RedisCommandRawReply>>; export type RedisClusterMultiExecutor = (queue: Array<RedisMultiQueuedCommand>, firstKey?: RedisCommandArgument, chainId?: symbol) => Promise<Array<RedisCommandRawReply>>;

View File

@@ -10,5 +10,5 @@ export function commandOptions<T>(options: T): CommandOptions<T> {
} }
export function isCommandOptions<T>(options: any): options is CommandOptions<T> { export function isCommandOptions<T>(options: any): options is CommandOptions<T> {
return options && options[symbol] === true; return options?.[symbol] === true;
} }

View File

@@ -70,7 +70,7 @@ export function extendWithModulesAndScripts<T extends Instantiable>(config: Exte
return (Commander ?? config.BaseClass) as any; return (Commander ?? config.BaseClass) as any;
} }
export function transformCommandArguments<T = unknown>( export function transformCommandArguments<T>(
command: RedisCommand, command: RedisCommand,
args: Array<unknown> args: Array<unknown>
): { ): {

View File

@@ -5,12 +5,10 @@ import { RedisServerDockerConfig, spawnRedisServer, spawnRedisCluster } from './
import yargs from 'yargs'; import yargs from 'yargs';
import { hideBin } from 'yargs/helpers'; import { hideBin } from 'yargs/helpers';
interface TestUtilsConfig<M extends RedisModules, S extends RedisScripts> { interface TestUtilsConfig {
dockerImageName: string; dockerImageName: string;
dockerImageVersionArgument: string; dockerImageVersionArgument: string;
defaultDockerVersion: string; defaultDockerVersion: string;
defaultClientOptions?: Partial<RedisClientOptions<M, S>>;
defaultClusterOptions?: Partial<RedisClusterOptions<M, S>>;
} }
interface CommonTestOptions { interface CommonTestOptions {
@@ -29,7 +27,7 @@ interface ClusterTestOptions<M extends RedisModules, S extends RedisScripts> ext
numberOfNodes?: number; numberOfNodes?: number;
} }
export default class TestUtils<M extends RedisModules, S extends RedisScripts> { export default class TestUtils {
static #getVersion(argumentName: string, defaultVersion: string): Array<number> { static #getVersion(argumentName: string, defaultVersion: string): Array<number> {
return yargs(hideBin(process.argv)) return yargs(hideBin(process.argv))
.option(argumentName, { .option(argumentName, {
@@ -52,7 +50,7 @@ export default class TestUtils<M extends RedisModules, S extends RedisScripts> {
readonly #DOCKER_IMAGE: RedisServerDockerConfig; readonly #DOCKER_IMAGE: RedisServerDockerConfig;
constructor(config: TestUtilsConfig<M, S>) { constructor(config: TestUtilsConfig) {
this.#DOCKER_IMAGE = { this.#DOCKER_IMAGE = {
image: config.dockerImageName, image: config.dockerImageName,
version: TestUtils.#getVersion(config.dockerImageVersionArgument, config.defaultDockerVersion) version: TestUtils.#getVersion(config.dockerImageVersionArgument, config.defaultDockerVersion)