将通用对象存储在类

时间:2016-10-23 01:17:26

标签: typescript typescript-generics

我正在编写一个Angular 2应用程序,并且有一个组件可以动态地将其他组件呈现给视图,如https://blog.thecodecampus.de/angular-2-dynamically-render-components/所述

该过程工作得很好,但是不是创建组件并从构造函数中迅速销毁它,我宁愿将该逻辑放在类中的另一个函数中,该函数确切地确定基于哪个组件被写入页面。一个输入。存在切换这些子组件中的哪一个的功能,因此我需要能够存储已解析的组件对象,以便稍后可以在其上调用destroy(),这会引导我们解决当前的问题。

我想将此对象存储在私有属性中的类上,但我无法弄清楚如何键入它。以下是.d.ts文件描述最初实例化对象的createComponent函数的内容:

abstract createComponent<C>(componentFactory: ComponentFactory<C>, index?: number, injector?: Injector, projectableNodes?: any[][]): ComponentRef<C>;

现在这一切都很好,但它有一个通用类型的C,当我传入需要解析的组件时已解决,但我想指定这是我可能传入的任何潜在组件。我不喜欢我不想仅仅将我的财产指定为'任何',因为随后的破坏将无法验证,例如

private _visibleElement: any;

现在,我确定可以对数组进行打字并说它可以是AppleComponent类型BananaComponent | CherryComponent等,但我希望这更灵活,每次我修改它时都不必保持这些保护,例如

private _visibleElement: ComponentRef<AppleComponent|BananaComponent|CherryComponent>;

我能想到的唯一其他方法是为这些组件创建一个空接口,每个都实现它然后组成这个类型,但是我只是将类型保护的维护切换到必须记住将接口应用于我将来添加的每个组件。

我可以采取其他任何方法,允许我指定一个对象属于泛型类型,而不必事先指定该类的泛型类型是什么?

谢谢!

1 个答案:

答案 0 :(得分:1)

基本界面必须包含某些东西,如果它是空的,那么一切都将被接受:

interface MyComponent {}

function create<T extends MyComponent>(comp: T) {}

create(4); // no error
create({ key: "value" }); // no error

code in playground

使用此方法并不需要您记住在未来的课程中应用界面,因为类型安全只会提醒您。
一旦你有了所有组件的这个基本接口,那么确保你有依赖于它的函数/类型,这样如果你引入一个新的组件类并且它没有实现BaseComponent那么编译器会抛出错误你试着用它。
例如,您可以:

type MyRef<T extends BaseComponent> = ComponentRef<T>;

然后随处使用:

abstract createComponent<C extends BaseComponent>(componentFactory: ComponentFactory<C>, index?: number, injector?: Injector, projectableNodes?: any[][]): MyRef<C>;