typescript - 链接静态 .plugin() 类方法以多次扩展实例 API
问题描述
我有一个插件架构,我允许我这样做
const fooPlugin = () => ({ foo: 'foo' })
const barPlugin = () => ({ bar: 'bar' })
const BaseWithPlugin = Base.plugin(fooPlugin)
const baseWithPlugin = new BaseWithPlugin()
baseWithPlugin.foo // ✅ string
const BaseWithPlugins = Base.plugin([fooPlugin, barPlugin])
const baseWithPlugins = new BaseWithPlugins()
baseWithPlugins.foo // ✅ string
baseWithPlugins.bar // ✅ string
但它无法做到这一点
const BaseWithPlugins2 = Base.plugin(fooPlugin).plugin(barPlugin)
const baseWithPlugins2 = new BaseWithPlugins2()
baseWithPlugins2.foo // ❌ Property 'foo' does not exist on type 'plugin<() => { bar: string; }>.BaseWithPlugins & { bar: string; }'.
baseWithPlugins2.bar // ✅ string
如果我创建另一个扩展BaseWithPlugin
并具有与静态方法完全相同的实现的类plugin
,我会得到预期的结果
class Workaround extends BaseWithPlugin {
static plugin<T extends TestPlugin | TestPlugin[]>(plugin: T) {
const currentPlugins = this.plugins;
const WorkaroundWithPlugins = class extends this {
static plugins = currentPlugins.concat(plugin);
};
type Extension = ReturnTypeOf<T>;
return WorkaroundWithPlugins as typeof WorkaroundWithPlugins & Constructor<Extension>;
}
}
const BaseWithPlugins3 = Workaround.plugin(barPlugin)
const baseWithPlugins3 = new BaseWithPlugins3()
baseWithPlugins3.foo // ✅ string
baseWithPlugins3.bar // ✅ string
我希望找到一种不需要这种解决方法的方法。这看起来像microsoft/TypeScript#5863中报告的错误。线程中提到了一些解决方法,但我认为它们中的任何一个都不适用于我的情况。
这是带有完整代码的游乐场。我还创建了一个存储库,其中包含 2 个重现问题的失败测试用例。我无法弄清楚如何进行链接.plugin().plugin()
或.plugin().defaults()
工作,或者今天的 TypeScript 是否有可能。我真的很感激任何帮助!
解决方案
这是带有解决方案的游乐场。
class Base {
static plugin<S extends Constructor<any> & { plugins: any[] }, T extends TestPlugin | TestPlugin[]>(this: S, plugin: T) {
const currentPlugins = this.plugins;
const BaseWithPlugins = class extends this {
static plugins = currentPlugins.concat(plugin);
};
type Extension = ReturnTypeOf<T>;
return BaseWithPlugins as typeof BaseWithPlugins & Constructor<Extension>;
}
}
您缺少的部分是您应该让plugin
静态函数也推断this
.
推荐阅读
- mysql - rails 5.2 应用程序记录的不正确 json 序列化
- postgresql - 获取子表 1 和子表 2 中没有特定值的父项的 SQL 查询
- android - 如何将阴影调整到 RTL SlidingMenu
- node.js - 使用网络主机模式运行 docker 容器
- python-3.x - numpy arange 函数返回不一致的数组
- dynamic-programming - 如果输入值很高,为什么需要 0-1 背包的近似解?
- azure-devops - 为 Azure DevOps 扩展创建配置窗格
- javascript - 选项卡式内容在没有 CSS 设置的情况下仅在屏幕上显示几毫秒,然后正确加载
- git - 在 GIT 中我们可以这样组合提交指针吗?
- amazon-web-services - AWS Lambda 和 API Gateway 响应集成问题