1

I'm using styled-components to build a message card component. I'm trying to make it have as little logic and take as few props as possible, so I'm using CSS to style any <p> or <svg> elements that are passed in as children like so:

Screenshot of MessageCard being used next to desired outcome.

I'm also using typescript and I'd like to ensure that the only element types passed in as children are a minimum of 1 paragraph element and 1 SVG element?

Something like this for example:

type = MessageCardProps = {
  children: [ JSXSVGElement?, JSXParagraphElement, JSXParagraphElement]
}

1 Answers1

2

It is currently not possible to implement it the way you want. Unfortunately ReactElement loosens type checking as described here: How do I restrict the type of React Children in TypeScript, using the newly added support in TypeScript 2.3?

After all Reacts Composition to use the props to pass this to your component with the appropriate types:

import { ComponentPropsWithoutRef, PropsWithChildren } from "react";

type MessageCardProps = PropsWithChildren<{
  icon: ComponentPropsWithoutRef<"svg">;
  title: string;
}>;

function MessageCard({ icon, title, children }: MessageCardProps) {
  return <div>{icon}{title}{children}</div>;
}

export default function App() {
  return (
    <MessageCard icon={<svg></svg>} title="title">
      message
    </MessageCard>
  );
}
Robin
  • 8,162
  • 7
  • 56
  • 101