DynamicZone component with TypeScript

Hello,

I’m working on migrate my portfolio from JS to TS and i got the next problem:
I have a model with a dynamic zone(we used Strapi-to-Typescript to get them) as follows:

export interface IPage {
  id: string;
  title?: string;
  slug: string;
  thumbnail?: IFile;
  body: (
    | ({ __component: "content.rich-text" } & IRichText)
    | ({ __component: "content.experience" } & IExperience)
    | ({ __component: "content.personal-information" } & IPersonalInformation)
    | ({ __component: "fields.skill" } & ISkill)
  )[]; // IComponent[]
  tags?: ITag[];
  description?: string;
}

I have a component how renderizes this body:

export const Body = ({ body }) => {
  return body.map((component) => (
    <DynamicZone key={`component${component.id}`} component={component} />
  ));
};

And the dynamic zone component is:

export const DynamicZone = ({ component, className }) => {
  const classes = useStyles();
  const { i18n } = useTranslation();

  return (
    <Typography
      variant="body1"
      component="section"
      className={clsx(classes.root, className)}
    >
      {
        {
          ComponentContentContent: (
            <Content>
                component
            </Content>
          ),
          ComponentFieldsSkill: <Skill {...component} />,
        }[component.__typename]
      }
    </Typography>
  );
};

It is like that since the normal GraphQL json response comes like:

"body": [
        {
          "__typename": "ComponentContentPersonalInformation",
          "id": "2",
          "name": "José Luis Sandoval Alaguna",
          "photo": {
            "alternativeText": "Profile photo.",
            "caption": "José Luis Sandoval Alaguna",
            "url": "https://res.cloudinary.com/dqhx2k8cf/image/upload/v1608399687/fotodeperfil_029e62c5d9.jpg",
            "width": 970,
            "height": 1296
          },
          "position": "Front-End Developer at CloudNesil",
          "nationality": "Colombian",
          "address": {
            "address": "6438 Sokak. Yunusemre Mah. No: 5 Daire: 1, Pamukkale",
            "city": "Denizli",
            "country": "Turkey",
            "postalCode": null
          },
          "telephone": [
            {
              "id": "1",
              "type": "Mobile",
              "number": 5373749236
            }
          ],
          "mail": "alagunasalahaddin@live.com",
          "links": [
            {
              "id": "1",
              "type": "LinkedIn",
              "url": "www.linkedin.com/in/jluissalaguna/"
            },
            {
              "id": "2",
              "type": "Github",
              "url": "www.github.com/SalahAdDin"
            },
            {
              "id": "3",
              "type": "StackOverflow",
              "url": "stackoverflow.com/users/3826549/salahaddin"
            }
          ],
          "aboutMe": null
        },
        {
          "__typename": "ComponentFieldsSkill",
          "type": "Language",
          "id": "6",
          "name": "Español (Native)",
          "level": 5
        },

So, migrating the dymanic zone we have:

type IComponent =
  | ({
      __component: "content.rich-text";
      __typename: "ComponentContentRichText";
    } & IRichText)
  | ({
      __component: "content.experience";
      __typename: "ComponentContentExperience";
    } & IExperience)
  | ({
      __component: "content.personal-information";
      __typename: "ComponentContentPersonalInformation";
    } & IPersonalInformation)
  | ({
      __component: "fields.skill";
      __typename: "ComponentFieldsSkill";
    } & ISkill);

interface IDynamicZone {
  component: IComponent;
  className?: string;
}

const DynamicZone: React.FC<IDynamicZone> = ({ component, className }) => {
  const classes = useStyles();
  return (
    <Typography
      variant="body1"
      component="section"
      className={clsx(classes.dynamicZone, className)}
    >
      {
        {
          ComponentContentContent: <Content>{component}</Content>,
          ComponentFieldsSkill: <Skill {...component} />,
        }[component.__typename]
      }
    </Typography>
  );
};

But, we are getting the next problems:

What’s the best way to handle a dynamic zone component?

Thanks

It’s been awhile since this question was asked.
Did you managed to figure it out ?
( I am in the same situation , would also like to know how to properly handle the dynamic classes in TS )

2 Likes