使用功能扩展打字

时间:2019-06-13 15:45:28

标签: typescript typescript-typings typescript-generics

我正在尝试使用一些插件创建一个js SDK。

我正在研究它的类型。

我的代码是这样的:

import Sdk from "./sdk";
import ProductsPlugin from "./sdk/plugins/products";
import UsersPlugin from "./sdk/plugins/users";

const sdk = new Sdk({
  apiBaseUrl: "http://www.foo.bar"
});

sdk.usePlugin(ProductsPlugin)
sdk.usePlugin(UsersPlugin)

此刻,我想用插件添加的方法扩展sdk:

sdk.ProductsPlugin.addProcut(....)

想法是要有一个小型SDK,可以通过客户端所需的插件进行扩展。

如何扩展类型,所以当我有sdk.ProductsPlugin.时,系统会自动提示建议添加的方法

到目前为止的代码是这样的:

class Sdk {
  usePlugin(PluginClass) {
    new PluginClass(this);
  }
}


class Plugin {
    sdk: Sdk;

    constructor(sdk: Sdk) {
        this.sdk = sdk;
        const pluginName = this.constructor.name.replace("Plugin", "");
        sdk[pluginName] = this;
    }
}

class FirstPlugin extends Plugin {

    boo(){
        alert(1)
    }
}


const instance = new Sdk()


instance.usePlugin(FirstPlugin)


instance.First.boo(); 

问题是我没有.First的自动完成功能

1 个答案:

答案 0 :(得分:1)

我想做您想做的事情,您可能需要放松一些内在的要求。

首先,编译器没有一种明晰的方式来理解sdk.usePlugin()将改变sdk type 以便具有更多的属性。最接近的结果是让sdk.usePlugin()返回更改类型的this,并在配置Sdk时使用方法链接(如fluent interface)。

第二,如果希望编译器静态知道Sdk下的插件名称,则需要将其作为{{1}的一部分的string literal类型提供。 }类型定义。也许Plugin甚至应该是一个依赖于此名称的generic类,(如果需要将其子类化才能有用,则可以抽象)

这是您可能要做的事情:

Plugin

Link to code

我希望能给您一些指导。祝你好运!