在TypeScript中动态添加函数声明

时间:2019-05-05 11:18:51

标签: typescript

我是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类关联的所有样板代码。能够动态添加类型声明在这里非常有用。

1 个答案:

答案 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