eBay / nice-modal-react

A modal state manager for React.
https://ebay.github.io/nice-modal-react
MIT License
1.96k stars 110 forks source link

Can the .show() method be smarter about its return type? #105

Open cssinate opened 1 year ago

cssinate commented 1 year ago

https://github.com/eBay/nice-modal-react/blob/979c283892c4f16a4a2d5ecf582d1500eca3807a/src/index.tsx#L216

Right now, the .show() method always returns Promise<unknown>. If I'm not mistaken, whatever I end up passing into .resolve() is what gets returned to .show().

I'm only still learning TypeScript, but can't you use generics to accept a type? Right now, I'm having to do a manual type-check method in order to assert my return type. It feels like I shouldn't have to do that.

For example, if when constructing the modal, you do

modal.resolve(true)

In the app when you do

modal.show().then((res) => whatever...

TypeScript thinks res is unknown. Surely there's a way I can assert that it's a boolean?

chen86860 commented 1 year ago

You can using NiceModal.show and pass generic type while calling it. eg:

  NiceModal.show<boolean>(someModal).then((res) => {
    // res is boolean you passed in
    console.log(res);
  });
tangdw commented 1 year ago

You can using NiceModal.show and pass generic type while calling it. eg:

  NiceModal.show<boolean>(someModal).then((res) => {
    // res is boolean you passed in
    console.log(res);
  });

能在 someModal 里面定义,然后 show 的时候自动推断吗?

kbzowski commented 7 months ago

Any chance to have types support also for imperative code (using hooks)?

const modal = useModal(MyModal);
...
modal.show<ReturnType>().then(result => {})
weiskopfsodefa commented 3 months ago

This would be very nice! Using the generic type from the .show() function doesn't really help, it's as good as casting my result as [some type] which doesn't have to be in sync with the actual return value. Also I have to look up what types my ModalComponent might return.

I think it should at least be a return type specified in the ModalComponent which is checked against my resolve values and then used by the .show() function.

Something like this:

const ConfirmDialog = NiceModal.create<
{
  //input
  title: string
}, 
  //output
  boolean
>(({ title }) => {
  const modal = useModal()
  ...
  // would error if resolve value is not typeof boolean
  modal.resolve(true)
  ...
})
// confirmResult is typeof boolean (specified from the output of ConfirmDialog)
const confirmResult = await NiceModal.show(
  ConfirmDialog,
  { title: 'Hi' }
)