首页 > 解决方案 > 如何在第三方模块上添加自定义类型?

问题描述

我正在使用 node.js 和 typescript 为后端编程。

我也为打字稿安装了“mysql”模块和“@types/mysql”模块。

如您所知,mysql 模块基本上不支持承诺模式。

当我使用 javascript 而不是 typescript 时,这段代码运行良好。

const pool = mysql.createPool(config);
pool.query = util.promisify(pool.query);

export default pool;

但是, 和 的类型pool.queryutil.promisify()打字稿中不匹配。

所以我正在尝试在interface Pool extends EscapeFunctionsin添加一个新属性node_modules/@types/mysql/index.d.ts

我应该node_modules/@types/mysql/index.d.ts直接编辑文件吗?

或者,有什么安全的方法吗?

标签: mysqlnode.jstypescript

解决方案


据我所知,默认情况下utils.promisify仅支持 node.js 样式的回调,看起来像(err, result) => void. 您的池查询回调被声明为类似(err, result, fields) => void. 所以简短的回答是,不,默认情况下你不能在这种情况下使用它。

但是如果你对方式感兴趣,你可以扩展utils.promisify声明以适应你的模块声明,你可以在你的项目中写这样的东西:

declare module "util" {
    function promisify<T1, TResult, TFields>(fn: (arg1: T1, callback: (err: any, result: TResult, fields: TFields) => void) => void): () => Promise<{ result: TResult, fields: TFields }>;
}

重新声明 promisify 后,您现在需要扩展您pool.query的支持以支持其他 args(如node.js 文档中所述),如下所示:

pool.query[util.promisify.custom] = <TResult, TFields>(query: string) => new Promise<{ result: TResult, fields: TFields }>((resolve, reject) => {
    pool.query(query, (err, result: TResult, fields: TFields) => {
        if (err) { reject(err) }
        else { resolve({ result, fields }) }
    })
});

现在您的 promisify 支持该模块,但它并不那么简单,只需手动声明 promise,甚至制作您自己的 promisify 函数,这将支持任意数量的参数。


推荐阅读