admin管理员组文章数量:1200979
Consider the following code:
import redis = require('redis'); //Has ambient declaration from DT
import bluebird = require('bluebird'); //Has ambient declaration from DT
bluebird.promisifyAll((<any>redis).RedisClient.prototype);
bluebird.promisifyAll((<any>redis).Multi.prototype);
const client = redis.createClient();
client.getAsync('foo').then(function(res) {
console.log(res);
});
getAsync
will error out because it's created on the fly and not defined in any .d.ts
file. So what is the proper way to handle this?
Also, even though I have the .d.ts
files loaded for redis, I still need to cast redis
to any
to be used for promisifyAll
. Otherwise, it will spill out error:
Property 'RedisClient' does not exist on type 'typeof "redis"'
Is typing it to any
the only easy way to go?
Consider the following code:
import redis = require('redis'); //Has ambient declaration from DT
import bluebird = require('bluebird'); //Has ambient declaration from DT
bluebird.promisifyAll((<any>redis).RedisClient.prototype);
bluebird.promisifyAll((<any>redis).Multi.prototype);
const client = redis.createClient();
client.getAsync('foo').then(function(res) {
console.log(res);
});
getAsync
will error out because it's created on the fly and not defined in any .d.ts
file. So what is the proper way to handle this?
Also, even though I have the .d.ts
files loaded for redis, I still need to cast redis
to any
to be used for promisifyAll
. Otherwise, it will spill out error:
Property 'RedisClient' does not exist on type 'typeof "redis"'
Is typing it to any
the only easy way to go?
- Have you ever found a way to resolve this? I am running into same issue... – zam6ak Commented Apr 13, 2016 at 13:31
- @zam6ak Yes by using declaration merging. See my answer below. – Dave Commented Apr 14, 2016 at 20:56
4 Answers
Reset to default 12I'm solving this by declaration merging the setAsync
& getAsync
methods. I added the following code in my own custom .d.ts
file.
declare module "redis" {
export interface RedisClient extends NodeJS.EventEmitter {
setAsync(key:string, value:string): Promise<void>;
getAsync(key:string): Promise<string>;
}
}
Another way to do it which requires less code is to extend the Redis object like so:
import { promisify } from 'util';
import { ClientOpts, RedisClient } from 'redis';
class AsyncRedis extends RedisClient {
public readonly getAsync = promisify(this.get).bind(this);
public readonly setAsync = promisify(this.set).bind(this);
public readonly quitAsync = promisify(this.quit).bind(this);
public readonly rpushAsync: (list: string, item: string) => Promise<number> = promisify(
this.rpush
).bind(this);
public readonly blpopAsync: (
list: string,
timeout: number
) => Promise<[string, string]> = promisify(this.blpop).bind(this);
public readonly flushdbAsync = promisify(this.flushdb).bind(this);
}
Notice that not all method signatures overwrite correctly, so you have to help typescript a little.
Now you can just use this enhanced class by creating it with your options, for example:
new AsyncRedis({
host: process.env.REDIS_HOST || '127.0.0.1',
password: process.env.REDIS_PASSWORD || 'whatever',
});
Just adding to Dave's answer, in my needs, I has to add in Multi for atomic operations.
declare module 'redis' {
export interface RedisClient extends NodeJS.EventEmitter {
execAsync(...args: any[]): Promise<any>;
hgetallAsync(...args: any[]): Promise<any>;
// add other methods here
}
export interface Multi extends Commands<Multi> {
execAsync(...args: any[]): Promise<any>;
// add other methods here
}
}
This solution works fine for me:
import { promisifyAll } from 'bluebird'; // import here works only if @types/bluebird is installed
import redis, { RedisClient, Multi } from 'redis'; // import here works only if @types/redis is installed
// Convert Redis client API to use promises, to make it usable with async/await syntax
const MultiAsync: any = promisifyAll(Multi.prototype);
const RedisClientAsync: any = promisifyAll(RedisClient.prototype);
const redisAsync = { ...redis, Multi: MultiAsync, RedisClient: RedisClientAsync };
const client: typeof RedisClientAsync = redisAsync.createClient();
// now you can use client async methods, i.e. client.getAsync, client.hgetAsync, client.hsetAsync, client.expireAsync...
本文标签: javascriptHow to properly deal with promisifyAll in typescriptStack Overflow
版权声明:本文标题:javascript - How to properly deal with promisifyAll in typescript? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738557488a2098577.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论