VSCode / Typescript 可以对插件修改的对象进行类型推断吗?

Can VSCode / Typescript do Type inference on plugin-modifed objects?

我很喜欢 VSCode 和 Typescript 的开发人员工效学。当我将插件应用到 pouchdb 包时出现了一个小问题:

import * as pouch from 'pouchdb-browser'
pouch.plugin(require('pouchdb-authentication'));

const remoteDB: PouchDB.Database<PouchDB.Core.Encodable> = new pouch(
    'https://user.cloudant.com/databaseName',
    { skip_setup: true } // a param wanted by the plugin
);

// invoking a method added by the plugin:
remoteDB.signup('username','password', (err, resp) => {console.log(err)} );

上面的代码可以在浏览器中运行,但是我的开发经验受到了阻碍,因为VSCode无法识别插件添加的方法:

这种类型推断是否超出了 VSCode 的范围?

注意:NPM 上没有此包的@types 包:https://www.npmjs.com/package/@types/pouchdb-authentication 是 404。这是缺少的部分吗?

据我从文档 (https://pouchdb.com/api.html#plugins) 中得知,plugin 方法使用您传递给它的任何内容来扩展您的 PouchDB.Database 对象。

实际上,如果你使用pouch.plugin(require('pouchdb-authentication'));,那么你的数据库就不再是PouchDB.Database<T>类型了;它实际上是该接口的扩展。所以 VSCode 抱怨的事实是正确的,因为你声明 remoteDB 的类型没有 signup 方法。

然后您可以为 remoteDB 创建您自己的接口,使用 pouchdb-authentication 添加的任何方法和属性扩展 PouchDB.Database<T>;例如

interface PouchDBSignupPlugin<T> extends PouchDB.Database<T> {
    signup: (username: string, password: string, handler: (err: any, resp: any) => void) => any;
}

并这样使用它:

const remoteDB = new pouch<PouchDB.Core.Encodable>(
    'https://user.cloudant.com/databaseName',
    { skip_setup: true } // a param wanted by the plugin
) as PouchDBSignupPlugin<PouchDB.Core.Encodable>;

然后你应该会发现 VSCode 并且 TypeScript 会识别 remoteDB 上的 signup 方法。