0

I just created a dynamic component what should look like the next:

/* Should inherit all InputComponent properties. DefaultComponent should be the default component props value. */

<DynamicComponent component={InputComponent} />

My current implementation looks like the next:

type DefaultProps = { defaultProp: string }
type InputProps = { onChange: () => void }
type DynamicType<P> = DynamicProps & { component: ReactType<P> } & P

export default function DynamicComponent(props: DynamicProps & { component?: DefaultComponent } & DefaultComponentProps): ReactElement<DefaultComponentProps>
export default function DynamicComponent<P>(props: DynamicType<P>): ReactElement<P> {
    const { style: overrideStyle, component } = props
    const { style } = getStyle(props)
    const mergedStyle = { ...style, ...overrideStyle }
    return React.createElement(component, { ...props, style: mergedStyle })
};

DynamicComponent.defaultProps = { component: DefaultComponent }

So I would expect the next to happen:

1.) When the component is not defined I expect the 1st override (the one with the default)

<DynamicComponent defaultProps='itsTotallyValid' /> // valid

2.) When the component is defined I expect to inherit it's properties

<DynamicComponent component={InputComponent} onChange={() =>{}} /> // valid

For some reason the 2nd situation never happens, and it's always selects the first one. Is there a way to be more strict, so I can force the 2nd situation to be possible?

Update

Example: https://codesandbox.io/s/quiet-architecture-zx60y

Istvan Orban
  • 1,607
  • 3
  • 18
  • 34

1 Answers1

0

Addressing the concern in the comments about the default generic type blocking type inference, that is not the case, the following minimal example demonstrates type inference working on type T which has a default of string,

function Bar<T = string>(props: { component: T }) : T {
  return props.component
}

Bar({ component : 'string' })
Bar({ component : 5 }) // <-- Type inferred to be number
Avin Kavish
  • 8,317
  • 1
  • 21
  • 36