Angular material dialog - pass types into dialog component Angular material dialog - pass types into dialog component typescript typescript

Angular material dialog - pass types into dialog component


TL;DR:

You can use the following code to specify the type that your dialog's data will use:

import { MatDialog } from '@angular/material/dialog';export class MyComponent {  constructor(private dialog: MatDialog) { }  openDialog() {    this.dialog.open<MyDialogComponent, MyType>(MyDialogComponent, {      data: {        // Your data goes here      }    };  }}

In your dialog component:

import { MAT_DIALOG_DATA } from '@angular/material/dialog';export class MyDialogComponent {  constructor(@Inject(MAT_DIALOG_DATA) public data: MyType) { }}

The open method of the MatDialog class actually allows three types to be specified (in order of sequence):

  • T: The component class (optional - although there's no default value, you don't have to specify it if you're just calling the method without any other types)
  • D: The type to be used for the data to be added to the dialog (optional - defaults to any)
  • R: The type to be used for the result of the dialog (optional - defaults to any)

The method is defined as below:

  /**   * Opens a modal dialog containing the given component.   * @param componentOrTemplateRef Type of the component to load into the dialog,   *     or a TemplateRef to instantiate as the dialog content.   * @param config Extra configuration options.   * @returns Reference to the newly-opened dialog.   */  open<T, D = any, R = any>(componentOrTemplateRef: ComponentType<T> | TemplateRef<T>,          config?: MatDialogConfig<D>): MatDialogRef<T, R> {    // ...  }

The D type is then passed to MatDialogConfig, which accepts the same type to be used for the data to be passed in to the dialog.


References:


I don't think it's possible to have a typed dialog the way you outlined it. But what you can do is something like:

export class MyDialog {    private savedForLater: SomeType;    constructor(            public containingDialog: MatDialogRef<MyDialog>,            @Inject(MAT_DIALOG_DATA) public data: SomeType) {        this.savedForLater = data;    }}

Unfortunately when you launch the dialog the type isn't enforced so you could still do this

const dialogData = {} as SomeTypeconst fakeDialogData = {} as SomeOtherTypethis.dialog.open(MyDialog, { data: dialogData });this.dialog.open(MyDialog, { data: fakeDialogData }); // this compiles