Skip to content

Commit

Permalink
fix: support TypeScript interface as parameters of hmset and mset (#1545
Browse files Browse the repository at this point in the history
)

Closes #1536
  • Loading branch information
luin committed Mar 30, 2022
1 parent d62a808 commit 3444791
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 70 deletions.
6 changes: 3 additions & 3 deletions bin/overrides.js
@@ -1,7 +1,7 @@
const msetOverrides = {
overwrite: false,
defs: [
"$1(object: Record<string, string | Buffer | number>, callback?: Callback<'OK'>): Result<'OK', Context>",
"$1(object: object, callback?: Callback<'OK'>): Result<'OK', Context>",
"$1(map: Map<string | Buffer | number, string | Buffer | number>, callback?: Callback<'OK'>): Result<'OK', Context>",
],
};
Expand All @@ -19,14 +19,14 @@ module.exports = {
hset: {
overwrite: false,
defs: [
"$1(key: RedisKey, object: Record<string, string | Buffer | number>, callback?: Callback<number>): Result<number, Context>",
"$1(key: RedisKey, object: object, callback?: Callback<number>): Result<number, Context>",
"$1(key: RedisKey, map: Map<string | Buffer | number, string | Buffer | number>, callback?: Callback<number>): Result<number, Context>",
],
},
hmset: {
overwrite: false,
defs: [
"$1(key: RedisKey, object: Record<string, string | Buffer | number>, callback?: Callback<'OK'>): Result<'OK', Context>",
"$1(key: RedisKey, object: object, callback?: Callback<'OK'>): Result<'OK', Context>",
"$1(key: RedisKey, map: Map<string | Buffer | number, string | Buffer | number>, callback?: Callback<'OK'>): Result<'OK', Context>",
],
},
Expand Down
14 changes: 4 additions & 10 deletions lib/utils/RedisCommander.ts
Expand Up @@ -4280,7 +4280,7 @@ interface RedisCommander<Context extends ClientContext = { type: "default" }> {
*/
hmset(
key: RedisKey,
object: Record<string, string | Buffer | number>,
object: object,
callback?: Callback<"OK">
): Result<"OK", Context>;
hmset(
Expand Down Expand Up @@ -4407,7 +4407,7 @@ interface RedisCommander<Context extends ClientContext = { type: "default" }> {
*/
hset(
key: RedisKey,
object: Record<string, string | Buffer | number>,
object: object,
callback?: Callback<number>
): Result<number, Context>;
hset(
Expand Down Expand Up @@ -5513,10 +5513,7 @@ interface RedisCommander<Context extends ClientContext = { type: "default" }> {
* - _complexity_: O(N) where N is the number of keys to set.
* - _since_: 1.0.1
*/
mset(
object: Record<string, string | Buffer | number>,
callback?: Callback<"OK">
): Result<"OK", Context>;
mset(object: object, callback?: Callback<"OK">): Result<"OK", Context>;
mset(
map: Map<string | Buffer | number, string | Buffer | number>,
callback?: Callback<"OK">
Expand All @@ -5537,10 +5534,7 @@ interface RedisCommander<Context extends ClientContext = { type: "default" }> {
* - _complexity_: O(N) where N is the number of keys to set.
* - _since_: 1.0.1
*/
msetnx(
object: Record<string, string | Buffer | number>,
callback?: Callback<"OK">
): Result<"OK", Context>;
msetnx(object: object, callback?: Callback<"OK">): Result<"OK", Context>;
msetnx(
map: Map<string | Buffer | number, string | Buffer | number>,
callback?: Callback<"OK">
Expand Down
92 changes: 35 additions & 57 deletions test/functional/transformer.ts
Expand Up @@ -5,85 +5,63 @@ import { expect } from "chai";
describe("transformer", () => {
describe("default transformer", () => {
describe("hmset", () => {
it("should support object", (done) => {
it("should support object", async () => {
const redis = new Redis();
redis.hmset("foo", { a: 1, b: "2" }, function (err, result) {
expect(result).to.eql("OK");
redis.hget("foo", "b", function (err, result) {
expect(result).to.eql("2");
done();
});
});
expect(await redis.hmset("foo", { a: 1, b: "2" })).to.eql("OK");
expect(await redis.hget("foo", "b")).to.eql("2");
});
it("should support Map", (done) => {

it("should support Map with string keys", async () => {
const redis = new Redis();
const map = new Map();
map.set("a", 1);
map.set("b", "2");
redis.hmset("foo", map, function (err, result) {
expect(result).to.eql("OK");
redis.hget("foo", "b", function (err, result) {
expect(result).to.eql("2");
done();
});
});
map.set(42, true);
map.set(Buffer.from("buffer"), "utf8");
map.set(Buffer.from([0xff]), "binary");
expect(await redis.hmset("foo", map)).to.eql("OK");
expect(await redis.hget("foo", "a")).to.eql("1");
expect(await redis.hget("foo", "b")).to.eql("2");
expect(await redis.hget("foo", "42")).to.eql("true");
expect(await redis.hget("foo", "buffer")).to.eql("utf8");
expect(await redis.hget("foo", Buffer.from([0xff]))).to.eql("binary");
});
it("should not affect the old way", (done) => {

it("should not affect the old way", async () => {
const redis = new Redis();
redis.hmset("foo", "a", 1, "b", "2", function (err, result) {
expect(result).to.eql("OK");
redis.hget("foo", "b", function (err, result) {
expect(result).to.eql("2");
done();
});
});
expect(await redis.hmset("foo", "a", 1, "b", "2")).to.eql("OK");
expect(await redis.hget("foo", "b")).to.eql("2");
});
});

describe("mset", () => {
it("should support object", (done) => {
it("should support object", async () => {
const redis = new Redis();
redis.mset({ a: 1, b: "2" }, function (err, result) {
expect(result).to.eql("OK");
redis.mget("a", "b", function (err, result) {
expect(result).to.eql(["1", "2"]);
done();
});
});
expect(await redis.mset({ a: 1, b: "2" })).to.eql("OK");
expect(await redis.mget("a", "b")).to.eql(["1", "2"]);
});
it("should support Map", (done) => {

it("should support Map", async () => {
const redis = new Redis();
const map = new Map();
map.set("a", 1);
map.set("b", "2");
redis.mset(map, function (err, result) {
expect(result).to.eql("OK");
redis.mget("a", "b", function (err, result) {
expect(result).to.eql(["1", "2"]);
done();
});
});
expect(await redis.mset(map)).to.eql("OK");
expect(await redis.mget("a", "b")).to.eql(["1", "2"]);
});
it("should not affect the old way", (done) => {

it("should not affect the old way", async () => {
const redis = new Redis();
redis.mset("a", 1, "b", "2", function (err, result) {
expect(result).to.eql("OK");
redis.mget("a", "b", function (err, result) {
expect(result).to.eql(["1", "2"]);
done();
});
});
expect(await redis.mset("a", 1, "b", "2")).to.eql("OK");
expect(await redis.mget("a", "b")).to.eql(["1", "2"]);
});
it("should work with keyPrefix option", (done) => {

it("should work with keyPrefix option", async () => {
const redis = new Redis({ keyPrefix: "foo:" });
redis.mset({ a: 1, b: "2" }, function (err, result) {
expect(result).to.eql("OK");
const otherRedis = new Redis();
otherRedis.mget("foo:a", "foo:b", function (err, result) {
expect(result).to.eql(["1", "2"]);
done();
});
});
expect(await redis.mset({ a: 1, b: "2" })).to.eql("OK");

const otherRedis = new Redis();
expect(await otherRedis.mget("foo:a", "foo:b")).to.eql(["1", "2"]);
});
});

Expand Down
51 changes: 51 additions & 0 deletions test/typing/transformers.test-d.ts
@@ -0,0 +1,51 @@
import { expectType } from "tsd";
import Redis from "../../built";

interface User {
name: string;
title: string;
}

const user: User = { name: "Bob", title: "Engineer" };
const stringMap = new Map([["key", "value"]]);
const numberMap = new Map([[42, "value"]]);
const bufferMap = new Map([[Buffer.from([0xff]), "value"]]);
const mixedMap = new Map<string | Buffer | number, string>([
[Buffer.from([0xff]), "value"],
[42, "value"],
["field", "value"],
]);

const redis = new Redis();

// mset
expectType<Promise<"OK">>(redis.mset("key1", "value1", "key2", "value2"));
expectType<Promise<"OK">>(redis.mset(user));
expectType<Promise<"OK">>(redis.mset(stringMap));
expectType<Promise<"OK">>(redis.mset(numberMap));
expectType<Promise<"OK">>(redis.mset(bufferMap));
expectType<Promise<"OK">>(redis.mset(mixedMap));

// msetnx
expectType<Promise<"OK">>(redis.msetnx(user));
expectType<Promise<"OK">>(redis.msetnx(stringMap));
expectType<Promise<"OK">>(redis.msetnx(numberMap));
expectType<Promise<"OK">>(redis.msetnx(bufferMap));
expectType<Promise<"OK">>(redis.msetnx(mixedMap));

// hmset
expectType<Promise<"OK">>(redis.hmset("key", user));
expectType<Promise<"OK">>(redis.hmset("key", stringMap));
expectType<Promise<"OK">>(redis.hmset("key", numberMap));
expectType<Promise<"OK">>(redis.hmset("key", bufferMap));
expectType<Promise<"OK">>(redis.hmset("key", mixedMap));

// hset
expectType<Promise<number>>(redis.hset("key", user));
expectType<Promise<number>>(redis.hset("key", stringMap));
expectType<Promise<number>>(redis.hset("key", numberMap));
expectType<Promise<number>>(redis.hset("key", bufferMap));
expectType<Promise<number>>(redis.hset("key", mixedMap));

// hgetall
expectType<Promise<Record<string, string>>>(redis.hgetall("key"));

0 comments on commit 3444791

Please sign in to comment.