Marek
Marek

Reputation: 63

Argument of type 'typeof Component' is not assignable to parameter of type 'ComponentType<Component>

I would like to have one service that opens different dialogs depending on from which components has service been called.

This is code from my service. pictureOfCode

public addEditItem(origin: string, item?: MoneyModel|BudgetItemModel|WorkflowModel|SportItemModel) {
    const dialogRef = this.dialog.open(this.pickDialog(origin), {
      data: {
        item: item ? item : null,
        origin: origin,
      },
      width: '500px',
  });
    dialogRef.afterClosed().subscribe(result => {
        this.data.next(result);
        console.log('The dialog was closed', result ? result : 'by clicking on cancel');
    });
}

public pickDialog(origin: string) {
    switch (origin) {
      case 'workflow': return AddEditWorkflowItemComponent;
      case 'sport': return AddEditSportItemComponent;
    }
}

It works when I run it locally, but build fails because of this error:

Argument of type 'typeof AddEditWorkflowItemComponent | typeof AddEditSportItemComponent' is not assignable to parameter of type 'ComponentType | TemplateRef'. Type 'typeof AddEditSportItemComponent' is not assignable to type 'ComponentType | TemplateRef'. Type 'typeof AddEditSportItemComponent' is not assignable to type 'ComponentType'. Property 'authors' is missing in type 'AddEditSportItemComponent' but required in type 'AddEditWorkflowItemComponent'.

Is there a way how I could convert the return from switch from typeof Component to ComponentType? Or, is there a way how I could switch the components that dialog opens in a better way? Any help is appreciated.

Upvotes: 3

Views: 8952

Answers (1)

Tiep Phan
Tiep Phan

Reputation: 12596

from your image, the prop authors is missing from AddEditSportItemComponent, so to fix your problem, you can treat pickDialog method to return any:

  const dialogRef = this.dialog.open((this.pickDialog(origin) as any), {
      data: {
        item: item ? item : null,
        origin: origin,
      },
      width: '500px',
  });

or create an interface which fit both AddEditWorkflowItemComponent and AddEditSportItemComponent and treat the method to return it.

export interface ComponentType<T = any> {
  new (...args: any[]): T;
}

public pickDialog(origin: string): ComponentType {
    switch (origin) {
      case 'workflow': return AddEditWorkflowItemComponent;
      case 'sport': return AddEditSportItemComponent;
    }
}

if 2 class is distinct, and you want to using type safe, you will end up with create 2 different methods for each type.

Upvotes: 0

Related Questions