I have a functional compopnent in dialog-functional.tsx
import { Slot } from 'vue';
export interface IDialog {
background: string;
alignRight: boolean;
};
type TSlotNames = 'default' | 'header' | 'footer';
type TDialogSlots = Readonly<Record<TSlotNames, Slot | undefined>>;
export default (props: { info: IDialog}, {slots}: {slots: TDialogSlots}) => {
return <div>
{/* header */}
<h1>Дијалог: {slots?.header?.()} </h1>
{/* body */}
<div style={{
"background-color" : props.info?.background ?? undefined,
"text-align": props.info?.alignRight ? "right" : undefined,
}}>
<div>Садржај:</div>
{ slots?.default?.() }
<div>
info: { JSON.stringify(props.info)}
</div>
</div>
<hr/>
{/* footer */}
<div>
Подножје: {slots?.footer?.()}
</div>
</div>
}
and I use it in test-demo.tsx:
import { defineComponent } from 'vue';
import csfDialog, { IDialog } from "./dialog-functional";
const proba = {
title: "Проба, аха",
};
const dlgInfo: IDialog = {
background: '#ffaaaa',
alignRight: true,
}
export default defineComponent({
// https://stackoverflow.com/a/64115658
components: {
csfDialog,
},
render() {
// use an array to return multiple root nodes
return <div>
<h1>Дијалог (with "v-slots"):</h1>
<csfDialog info={dlgInfo} v-slots={
{
footer: () => <div>Садржај <b>подножја</b></div>,
header: () => `Наслов`
}
}>
Ово је основни садржај са <b>анотацијом</b> гдје год треба
</csfDialog>
</div>
}
})
However I get an error when registering the functional component csfDialog with:
export default defineComponent({
components: {
csfDialog,
},
// ...
}
No overload matches this call.
The last overload gave the following error.
Type '(props: { info: IDialog;}, { slots }: { slots: TDialogSlots; }) => JSX.Element' is not assignable to type 'Component<any, any, any, ComputedOptions, MethodOptions>'.ts(2769)
NOTE 1
If I cast it into a Vue Component it works fine:
import { Component } from 'vue';
export default defineComponent({
components: {
csfDialog: (csfDialog as unknown) as Component,
},
// ...
}
NOTE 2
It seems that if the functional component is imported with the .jsx extension (even though it has .tsx extension):
// import csfDialog, { IDialog } from "./dialog-functional";
import csfDialog, { IDialog } from "./dialog-functional.jsx";
``
The types will be better recognized but I cannot enumerate slots anymore, as I get error:
Types of property 'slots' are incompatible. Type 'Readonly' is missing the following properties from type 'Readonly<Record<TSlotNames, Slot | undefined>>': default, header, footerts(2769)
so I have to reduce typings:
```ts
import { Slot, Slots } from 'vue';
// ...
export default (props: { info: IDialog}, {slots}: {slots: Slots}) => {
// ...
}
With this I have no errors anymore, but
- awkard file extension issue
.tsx->.jsx(I assume something with JSX/Vue management of TS imports) - not being able to strict slots anymore