如何正确处理打字稿中的promisifyAll?

Dav*_*ave 9 javascript promise typescript bluebird

请考虑以下代码:

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);
});
Run Code Online (Sandbox Code Playgroud)

getAsync将错误输出,因为它是在运行中创建的,并且未在任何.d.ts文件中定义.那么处理这个问题的正确方法是什么?

此外,即使我有.d.ts加载redis的文件,我还需要投redisany用于promisifyAll.否则,它会溢出错误:

Property 'RedisClient' does not exist on type 'typeof "redis"'
Run Code Online (Sandbox Code Playgroud)

输入它any是唯一容易的方法吗?

Dav*_*ave 7

我被解决这一声明合并setAsyncgetAsync方法.我在自己的自定义.d.ts文件中添加了以下代码.

declare module "redis" {

    export interface RedisClient extends NodeJS.EventEmitter {
        setAsync(key:string, value:string): Promise<void>;
        getAsync(key:string): Promise<string>;
    }

}
Run Code Online (Sandbox Code Playgroud)

  • 对大型图书馆来说这是可维护的吗?如果你使用了很多方法的lib,那么你需要重新声明所有*Async()方法吗?因为那会很乏味...... (2认同)

Ale*_*lex 5

另一种需要较少代码的方法是像这样扩展Redis对象:

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);
}
Run Code Online (Sandbox Code Playgroud)

请注意,并非所有方法签名都正确覆盖,因此您必须稍微帮助打字稿。

现在您可以通过使用您的选项创建它来使用这个增强类,例如:

new AsyncRedis({
  host: process.env.REDIS_HOST || '127.0.0.1',
  password: process.env.REDIS_PASSWORD || 'whatever',
 });
Run Code Online (Sandbox Code Playgroud)