I guess the hardest part about this question was to find a suitable title
So actually what I try to achieve is to render specific slides - but still.. every slide.. is actually a slide by data
lets look at what I mean and what I get from the api
type SomeSlideType = {
type: 'SomeSlide';
label: string;
headline: string
}
type SomeOtherSlideType = {
type: 'SomeOtherSlide';
members: number;
totalViews: number;
}
type AndAnotherSlideType = {
type: 'AndAnotherSlide';
someProp: string
someOtherProp: number;
}
type SlideType = {
sys: { id: string };
nextSlide: { id: string };
slide: SomeSlideType | SomeOtherSlideType | AndAnotherSlideType;
};
and in the end I get an array of slides => SlideType[]
So actually what I want to do is render them and still get the comfort of typesupport within the slides What I NOT want to have, is some big chunk of if else cluster like that:
export const Example = ({ slides }: { slides: SlideType[] }) => (
<div>
{
slides.map(slide => (
<>
{
slide.slide.type === "SomeSlide" ? (
<SomeSlide slideData={slide} />
) : slide.slide.type === "SomeOtherSlide" ? (
<SomeOtherSlide slideData={slide} />
) : slide.slide.type === "AndAnotherSlide" ? (
<AndAnotherSlide slideData={slide} />
) : null
}
</>
))
}
</div>
)
This way I would get the specific slide type info, but as there are many different slides (and many more to come) I'd love to go for an more dynamic approach like that:
const SLIDES_MAP: Record<
SlideType["slide"]["type"],
((props: SlideType) => JSX.Element)
> = {
SomeSlide: SomeSlideComponent,
SomeOtherSlide: SomeOtherSlideComponent,
AndAnotherSlide: AndAnotherSlideComponent
};
const Slide = ({ slideData }: ISlideProps) => {
const RenderSlide = SLIDES_MAP[slideData.slide.type];
if (!RenderSlide) return null;
return (
<RenderSlide
slide={slideData.slide}
sys={slideData.sys}
nextSlide={slideData.nextSlide}
/>
);
};
export const Example = ({ slides }: { slides: SlideType[] }) => (
<div>
{
slides.map(slide => (
<Slide slideData={slide} />
))
}
</div>
)
With that a slide itself would look something like that:
const SomeSlideComponent = ({
slide,
nextSlide,
sys,
}: SlideType & { slide: SomeSlideType }) => ( // <====== interesting part
<h1>
{slide.headline}
</h1>
);
export default SomeSlideComponent;
Of course it now complains, that the return type of SomeSlideComponent doesn't match with ((props: SlideType) => JSX.Element) as we manipulated the type to SlideType & { slide: SomeSlideType } to specify it (and SomeSlideType !== SomeSlideType | SomeOtherSlideType | AndAnotherSlideType
Still, to come to the MAIN question, with SlideType & { slide: SomeSlideType } I thought somehow I could define it as a valid "value" as I defined the SlideType earlier with:
type SlideType = {
sys: { id: string };
nextSlide: { id: string };
slide: SomeSlideType | SomeOtherSlideType | AndAnotherSlideType;
};
so SomeSlideType is actually a valid option for slide
anyone has an idea how to tackle this? some TS trick? I tried to use Partial<XYZ> too, but maybe I'm just to unskilled with that
I really hope I could pin down the issue in an understandable way, otherwise please feel free to request a more specific description on something :)
Thank you and cheers!