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

Support optional component props generic in `NiceModalArgs`? #80

Open oroszi1mark opened 1 year ago

oroszi1mark commented 1 year ago

Hello, thanks for this great tool, it's a joy to work with!

When passing optional props to the registered modal component (and the component type passes a condition in type NiceModalArgs<T>), the component props are typed as Partial<Omit<React.ComponentProps<T>, 'id'>>.

Using Partial<> means that otherwise required component props are incorrectly loosened up. The related comment specifically mentions using Partial<>, so I guess there was a good reason to do so. But to achieve type safety, now a wrapper function must be used that enforces the required component props:

function registerModalWithProps<C extends React.FC<any>>(id: string, component: C, props: React.ComponentProps<C>) {
  register(id, component, props)
}

Could this situation be avoided if an optional component props generic were to be introduced?

type ReactJSXOrConstructor<T> = T extends keyof JSX.IntrinsicElements | React.JSXElementConstructor<any> ? T : never

type PartialComponentProps<T> = Partial<React.ComponentProps<ReactJSXOrConstructor<T>>>

declare type NiceModalArgs<T, P = PartialComponentProps<T>> = T extends ReactJSXOrConstructor<T> ? Omit<P, 'id'> : Record<string, unknown>;

I understand the optional generic would creep into the signatures of useModal(), register(), and possibly even show(), so an on-demand wrapper function might be simpler overall.