我是TypeScript的新手,并尝试实现一种自动生成的构建器模式,以便我可以按照...写一些东西
class Foo {
@buildable('inBar')
public bar = 'Uninitialized';
constructor() {}
}
const FooBuilder = getBuilder<Foo>(Foo);
const foo = new FooBuilder().inBar('My Bar').build();
为此写the code或多或少是很简单的,考虑到我不仅是TS的新手,而且已经离开JS一段时间了。
但是,当然,现在编译器会抱怨不知道inBar
函数。我可以使用[]
之类的const foo = new FooBuilder()['inBar']('My Bar').build();
运算符,但是这种语法在某种程度上不利于最初使用构建器模式的目的,这应该会提高可读性。
是否有某种方法可以向类型动态添加函数?也许使用reflect-metadata
API?
我知道装饰器不应该向装饰的类添加方法,但是在这种情况下,我试图动态创建一个新类,以避免必须编写和维护与builder类关联的所有样板代码。能够动态添加类型声明在这里非常有用。
答案 0 :(得分:2)
JS非常动态,但是TS不是。关于TS中的打字系统,它主要是功能性的或纯的。 AFAIK唯一的副作用-功能是declaration merging。动态添加声明取决于此功能。
这个想法很简单:在JS端动态创建builders
时,为了相应地反映这些正在进行的事件,您还应该在TS端“动态”扩展注册表界面。
这是要点。请查看此TS playground以获取完整示例。
// Empty interface, to be expanded later
interface BuilderRegistry {}
const builderRegistry: IBuilderRegistry = {} as any
class Foo {
@buildable('inBar')
public bar = 'Uninitialized';
constructor() {}
}
interface IFooBuilder extends Builder<Foo> {
inBar(val: string): IFooBuilder
}
// Expand IBuilderRegistry interface
interface IBuilderRegistry {
'Foo': { new(): IFooBuilder }
}
const FooBuilder = getBuilder<'Foo'>(Foo);
const foo = new FooBuilder().inBar('My Bar').build(); // all good