types: Component cannot be rendered with JSX
Version
3.0.5
Reproduction link
https://codesandbox.io/s/boring-babbage-lgpd9?file=/src/main.tsx
Steps to reproduce
Try to compile declare const Foo: Component; return <Foo />
What is expected?
No errors. <Bar />
should complain about a missing id
prop.
What is actually happening?
JSX element type 'Foo' does not have any construct or call signatures
This was broken with h(Foo)
too until #3219
It's a component passed in to a function from the user. The DefineComponent
type mangles required prop types by passing them through ExtractPropTypes
again. Component
uses ComponentPublicInstanceConstructor
which isn't exported. I basically need FunctionalComponent<Props> | ComponentPublicInstanceConstructor<Props>
Update: { new (): ComponentPublicInstance<Props> } | FunctionalComponent<Props>
seems to do what I want.
I mean use defineComponent to create components
const Comp = defineComponent({ /* ... */ })
Comp always conforms to the use in TSX
We do, this is for a config that people can pass components into:
new Vuetify({
iconSets: {
fa5: FontAwesomeIcon
}
})
I need a type that both:
- Accepts components of any type (functional or defineComponent)
- Lets me render that component (
<options.iconSets.fa5 />
)
use defineComponent to create components
Again I'm not the one creating these components, but defineComponent
doesn't allow functional components. If you pass it a function it turns it into setup
instead.
I ended up using { new (): ComponentPublicInstance<Props> } | FunctionalComponent<Props>
for this but I'd expect the builtin Component
type to just work without any messing around.
This is a tricky one, Component
should be the most generic valid component type.
TSX requires a type with a constructor to be able to render, which causes problems because Component
does not require a constructor, because {}
is a valid vue component.
There's no good solution for this, I think the Component
is the wrong type to be used with TSX don't know if adding a new type is ideal, but this would probably work:
type ComponentTSX<Props = {}> = Component<Props> & { new (): ComponentPublicInstance<Props> }
declare const Foo: ComponentTSX;
declare const Bar: ComponentTSX<{ id: string }>;
() => [<Foo />, <Foo id="ok" />, <Bar id="ok" />];