我有一个插件架构,我允许我这样做
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 中报告的错误。线程中提到了一些解决方法,但我认为它们中的任何一个都不适用于我的情况。
这是 the Playground with the full code 。我也有 created a repository with 2 failing test cases that reproduce the problem 。我无法弄清楚如何使
.plugin().plugin()
或 .plugin().defaults()
的链接工作,或者是否可以使用今天的 TypeScript。我真的很感激任何帮助! 最佳答案
这是 the Playground with solution 。
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
的类型。关于typescript - 链接静态 .plugin() 类方法以多次扩展实例 API,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58636914/