Home > Blockchain >  Generic props for React component
Generic props for React component

Time:10-30

I have a Linechart component

<LineChart/>

This component should take two props xField and yField both strings. For this I create the prop type

type Props = {
    xField:string,
    yField:string
}
// e.g <LineChart xField="Date" yField="EUR"/>

This component should also take an array of data points (an object with two keys)

example:

<LineChart xField="Date" yField="EUR" data={[
  {Date:"22.2.2022", EUR:231}
  {Date:"23.2.2022", EUR:142}
  {Date:"24.2.2022", EUR:152}
]}/>

Now, the keys of the objects in the data array should be restricted to be either the value of xField or yField

<LineChart xField="Date" yField="EUR" data={[
  {Date:"22.2.2022", EURO:231} //Compile error since "EURO" is not a valid key
  {Date:"23.2.2022", EURO:142}
  {Date:"24.2.2022", EURO:152}
]}/>



<LineChart xField="Date" yField="EUR" data={[
  {Date:"22.2.2022", EUR:231} //No compile error. EUR is a valid key since yField = "EUR"
  {Date:"23.2.2022", EUR:142}
  {Date:"24.2.2022", EUR:152}
]}/>

How can I modify the Props of my Linechart component to match this behavior? Is what I'm trying to achieve even possible?

My Linechart component looks like the following

export default function LineChart({ data, xField, yField }: Props) {
  const config: LineConfig = {
    data,
    xField,
    yField,
    slider: {
      start: 0.1,
      end: 0.5,
    },
  };

  return <Line {...config} style={{ gridRow: "2/4", gridColumn: "2/8" }} />;
}

CodePudding user response:

You can use generics for handling this. Set a type for the x and y which extends string. Then, use that type as keys for the data array.

interface Props<X extends string, Y extends string> {
  x: X;
  y: Y;
  data: Array<{ [k in X | Y]: k extends X ? string : number }>;
}

function MyComponent<X extends string, Y extends string>(
  props: Props<X, Y>
): JSX.Element {
  return <div />;
}

function MyComponent2() {
  return (
    <MyComponent
      x="Date"
      y="Eur"
      data={[
        { Date: '20-10-2022', Eur: 1 },
        { Date: '20-10-2022', Eur: 1 },
        { Date: '20-10-2022', Eur: 1 },
      ]}
    />
  );
}
  • Related