stipsan / ioredis-mock

Emulates ioredis by performing all operations in-memory.
MIT License
333 stars 125 forks source link

Unable to use with Typescript and NodeNext #1346

Open kristianmandrup opened 3 months ago

kristianmandrup commented 3 months ago

I've been trying to use this without success in typescript with nodenext. I installed typings from @types/ioredis-mock

import { redisMock } from "ioredis-mock";
const mockSender = new RedisSender(new redisMock());
import { redisMock } from "ioredis-mock";
         ^^^^^^^^^
SyntaxError: The requested module 'ioredis-mock' does not provide an export named 'redisMock'
import Redis from "ioredis-mock";
const mockSender = new RedisSender(new Redis());
This expression is not constructable.
  Type 'typeof import("/Users/kristian/repos/agent-communication-hub/node_modules/@types/ioredis-mock/index")' has no construct signatures.

The typings includes an index.d.ts which looks as follows:

/// <reference types="node" />

import ioredis = require("ioredis");

export type RedisOptions = { data?: Record<string, unknown> } & ioredis.RedisOptions;

export type RedisClusterOptions = {
    redisOptions: Omit<
        RedisOptions,
        "port" | "host" | "path" | "sentinels" | "retryStrategy" | "enableOfflineQueue" | "readOnly"
    >;
} & ioredis.ClusterOptions;

export interface ClusterConstructor {
    new(startupNodes: ioredis.ClusterNode[], options?: RedisClusterOptions): ioredis.Cluster;
}

export interface Constructor {
    new(port: number, host: string, options: RedisOptions): ioredis.Redis;
    new(path: string, options: RedisOptions): ioredis.Redis;
    new(port: number, options: RedisOptions): ioredis.Redis;
    new(port: number, host: string): ioredis.Redis;
    new(options: RedisOptions): ioredis.Redis;
    new(port: number): ioredis.Redis;
    new(path: string): ioredis.Redis;
    new(): ioredis.Redis;
    Cluster: ClusterConstructor;
}

export const redisMock: Constructor;
export { redisMock as default };

I can see there is an old issue on this https://github.com/stipsan/ioredis-mock/issues/661#issuecomment-1344836474

It works if I add my own ioredis.d.ts file as follows where redisMock is capitalized to RedisMock

/// <reference types="node" />

import ioredis = require("ioredis");

export type RedisOptions = {
  data?: Record<string, unknown>;
} & ioredis.RedisOptions;

export type RedisClusterOptions = {
  redisOptions: Omit<
    RedisOptions,
    | "port"
    | "host"
    | "path"
    | "sentinels"
    | "retryStrategy"
    | "enableOfflineQueue"
    | "readOnly"
  >;
} & ioredis.ClusterOptions;

export interface ClusterConstructor {
  new (
    startupNodes: ioredis.ClusterNode[],
    options?: RedisClusterOptions
  ): ioredis.Cluster;
}

export interface Constructor {
  new (port: number, host: string, options: RedisOptions): ioredis.Redis;
  new (path: string, options: RedisOptions): ioredis.Redis;
  new (port: number, options: RedisOptions): ioredis.Redis;
  new (port: number, host: string): ioredis.Redis;
  new (options: RedisOptions): ioredis.Redis;
  new (port: number): ioredis.Redis;
  new (path: string): ioredis.Redis;
  new (): ioredis.Redis;
  Cluster: ClusterConstructor;
}

export const RedisMock: Constructor;
export { RedisMock as default };
AaronPorts commented 2 weeks ago

import redisMock from "ioredis-mock";
const mockSender = new RedisSender(new redisMock.default());
kristianmandrup commented 2 weeks ago

Ah, thanks. Wasn't entirely clear from the docs. I also managed to get the linter to accept it by simply changing the import to:

import RedisMock from "ioredis-mock";
const redis = new RedisMock();