Joel Joel - 1 year ago 154
TypeScript Question

Enforce type in typescript by using interfaces

I'm using something similar to this to render dynamic modals.

The directive has an input that takes the type a the Component that it will render:

@Directive({ selector: '[ngComponentOutlet]' })
export class NgComponentOutlet implements OnChanges {
@Input() ngComponentOutlet: Type<any>;
@Input() ngOutletInjector: Injector;
@Input() ngOutletProviders: Provider[];
@Input() ngOutletProjectableNodes: any[][];

ngOutletCreated = new EventEmitter<ComponentRef<any>>(false);

private _cmpFactoryResolver: ComponentFactoryResolver,
private _viewContainerRef: ViewContainerRef) { }

ngOnChanges(changes: SimpleChanges) {
if (changes.hasOwnProperty('ngComponentOutlet')) {

if (this.ngComponentOutlet) {
let injector = this.ngOutletInjector || this._viewContainerRef.parentInjector;

if (Array.isArray(this.ngOutletProviders) && this.ngOutletProviders.length > 0) {
injector = ReflectiveInjector.resolveAndCreate(this.ngOutletProviders, injector);

const cmpRef = this._viewContainerRef.createComponent(
this._viewContainerRef.length, injector, this.ngOutletProjectableNodes);


I would like to enforce an interface on the components that can be used like this, so that I know that all Components dynamically rendered has a certain function, for example:

export interface ModalContent {
close(): void;

All the components that are going to be dynamic modals implements this:

export class MyCustomModalComponent implements ModalContent {
close() {

And then I put it all together

template: `<div [ngComponentOutlet]="component"></div>`,
export class AppComponent {
private component: ModalContent;

showModal() {
this.component = MyCustomModalComponent; <-- I get the error here

My problem is that I get the following error in AppComponent:

Type 'typeof MyCustomModalComponent' is not assignable to type 'ModalContent'.
Property 'close' is missing in type 'typeof MyCustomModalComponent'.

I guess it has to do with how I handle the types along the way, but I'm now sure what the problem is?

EDIT I added the entire Directive for reference

Answer Source

This code says component is of type ModalContent which means it can hold an instance of ModalContent.

private component: ModalContent;

This code assigns an instance of type Type, not of type ModalContent

this.component = MyCustomModalComponent;

This code would comply to the type annotations

this.component = new MyCustomModalComponent();

but you are not supposed to instantiate components yourself but instead let Angulars DI do it for you.

Not sure what you actually try to accomplish though.


If you actually want to assign a reference to the type, this should work:

private component: Type<ModalContent>
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download