ngneat / dialog

👻 A simple to use, highly customizable, and powerful modal for Angular Applications

Home Page:https://ngneat.github.io/dialog/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Strict modal typings

riccardoperra opened this issue · comments

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report  
[ ] Performance issue
[X] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:

Current behavior

Using the method open of dialogService with custom components, we have to manually put the generics "Data" and "Result" to get a typed interface like the example above:

// dialog component

import { DialogService, DialogRef } from '@ngneat/dialog';

export interface Input {
  value: string;
  object: {};
  num: number;
  sym: symbol;
}

export interface Output {
  outputData: string[]
}

@Component({
  template: `
    <h1>Hello World</h1>
    <button (click)="ref.close()">Close</button>
  `
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class HelloWorldComponent {
  constructor(public ref: DialogRef<Input, Output>) {}
}
// app component

import { DialogService } from '@ngneat/dialog';

@Component({
  template: `
    <button (click)="open()">Open</button>
  `
})
export class AppComponent implements OnInit {
  constructor(private dialog: DialogService) {}

  ngOnInit() {
    const dialogRef = this.dialog.open(HelloWorldComponent, {
    // no errors - data should be "Input" type
    // I expect: Type string is not assignable to Type Input
     data: 'i can pass any value'
    });
    // no errors - data should be "Output" type
    // I expect: Type "any" is not assignable to Type Output
    dialogRef.afterClosed$.susbcribe(data => data.no.typing.inference)
  }
}

What is the motivation / use case for changing the behavior?

Auto typing inference when we pass a component with a DialogRef in the constructor onto DialogService could be useful

Since this library uses the newest version for Angular and Typescript, this could be done using Conditional and recursive types. If it's ok I could create a simple pr to work on this.

Since I realize that not everyone might like it, we could make this feature optional, still allowing you to pass a generic Data and Result without typing checking. This is also needed to continue to support other type of parameters like TemplateRef.

For example:

this.dialog.open<string, number>(HelloComponent, {
  // data is string
  data: 'string'
}).afterClosed$.subscribe(result => // result is number )

but if no generic are provided

this.dialog.open(HelloComponent, {
  // data will be input of HelloComponent DialogRef<Input, Output> 
 // type-error
  data: 'string'
}).afterClosed$.subscribe(result => // result is DialogRef output )

Environment


Angular version: X.Y.Z


Browser:
- [ ] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
 
For Tooling issues:
- Node version: XX  
- Platform:  

Others:

You're welcome to create a PR

Done 😄

Guess this issue can be closed then?