I'm building a site using Prismic, Gatsby, and Typescript. Part of the appeal of Prismic is the slice feature, which allows you to create dynamic content sections that are easier for content editors to use. I've got a component called SliceZone
that maps through all the slices on a page:
SliceZone.tsx
import React from 'react';
import { ImageCta } from 'components/slices/call-to-action/image/ImageCta';
import { Columns } from 'components/slices/columns/Columns';
import { ContentBlock } from 'components/slices/content-block/ContentBlock';
import { Embed } from 'components/slices/embed/Embed';
import { TextHero } from 'components/slices/hero/text/TextHero';
import { Slider } from 'components/slices/slider/Slider';
import { Video } from 'components/slices/video/Video';
interface PageSlicesProps {
slices: any;
}
const PageSlices = ({ slices }: PageSlicesProps) => {
const sliceComponents = {
hero: TextHero,
slider: Slider,
content_block: ContentBlock,
video: Video,
columns: Columns,
embed: Embed,
image_call_to_action: ImageCta,
};
return slices.map((slice: any, index: number) => {
const SliceComponent = sliceComponents[slice.type];
if (SliceComponent) {
return <SliceComponent slice={slice} key={`slice-${slice.type}-${index}`} />;
}
});
};
interface SliceZoneProps {
bodyContent: any;
}
export const SliceZone = ({ bodyContent }: SliceZoneProps) => <PageSlices slices={bodyContent.body} />;
and I'm needing to appropriately type everything. However, I'm getting this error on SliceComponent
, specifically sliceComponents[slice.type]
:
Element implicitly has an 'any' type because expression of type 'any' can't be used to index type '{ hero: ({ slice }: any) => Element; slider: ({ slice }: any) => Element; content_block: ({ slice }: any) => Element; video: ({ slice }: any) => Element; columns: ({ slice }: any) => Element; embed: ({ slice }: { ...; }) => Element; image_call_to_action: ({ slice }: any) => Element; }'.
How do I create an interface
that will appropriately type this? I'm sorry if my question is somewhat muddy, I'm new to React and to Typescript, so the language is a bit gone on me as of yet.
The issue is when your mapping of
const sliceComponents =
. It's missing a signature, so the return type is implicitlyany
. As the error says.You could make it explicit by saying you have a list of React class components/function components?
The
|
is a union operator. This says it can be either of these types.But I think would be better to create a common slice class that extends the React Component class.
And have your slice components extend that.
Then when you map them to their components you can say they are of type SliceComponent. And compiler now knows the component should have the correct props.
Check this stack