Typescript Interface for Recharts Custom Tooltip

Viewed 6788

Being not well-versed with Typescript yet, I am trying to create a custom Tooltip content for my Recharts chart in my React app with Typescript. @types/recharts has already been installed as one of the a devDependencies.

However, when I define the CustomTooltip function as shown below, Typescript is throwing an error

Binding element 'active' implicitly has an 'any' type. TS7031

How can we solve this issue?

const CustomTooltip = ({ active, payload, label }) => {
    if (active) {
        return (
        <div className="custom-tooltip">
            <p className="label">{`${label} : ${payload[0].value}`}</p>
            <p className="desc">Anything you want can be displayed here.</p>
        </div>
        );
    }

    return null;
}

return (
    <ComposedChart data={data}>
        ...
        <Tooltip content={<CustomTooltip />} />
    </ComposedChart>
)

Tried defining an interface, but got another error

Type '{}' is missing the following properties from type 'ICustomToolip': active, payload, label TS2739

interface ICustomToolip {
    active: any;
    payload: any;
    label: any;
}

const CustomTooltip = ({ active, payload, label }: ICustomToolip) => {
    if (active) {
        return (
        <div className="custom-tooltip">
            <p className="label">{`${label} : ${payload[0].value}`}</p>
            <p className="desc">Anything you want can be displayed here.</p>
        </div>
        );
    }

    return null;
}
6 Answers

Try to do the following (using rechart's types).

But keep in mind, that You have to add @types/recharts npm package ;)

import { TooltipProps } from 'recharts';
import {
  ValueType,
  NameType,
} from 'recharts/src/component/DefaultTooltipContent';

const CustomTooltip = ({
  active,
  payload,
  label,
}: TooltipProps<ValueType, NameType>) => {
  if (active) {
    return (
      <div className="custom-tooltip">
        <p className="label">{`${label} : ${payload?.[0].value}`}</p>
        <p className="desc">Anything you want can be displayed here.</p>
      </div>
    );
  }

  return null;
};

return (
  <ComposedChart data={data}>
    ...
    <Tooltip content={<CustomTooltip />} />
  </ComposedChart>
);

The accepted answer is wrong and will fail in projects where typescript is configured correctly and any is forbidden.

Use:

const CustomTooltip = ({ active, payload, label }: TooltipProps<number, string>): JSX.Element => {

Change number and string to your data types. You can also use it with the ValueType and NameType, but it makes more sense to declare it with your types.

const CustomTooltip = ({ active, payload, label }: TooltipProps<ValueType, NameType>): JSX.Element => {

usually

TooltipProps<number, string>

but depends on you graph data, so generically

TooltipProps<ValueType, NameType>

Here's some code that may help people. I'm using typescript btw. I did this without an explicit interface, just an any type like so.

                `{ 
                    'time': item.DateTime.getTime(),
                    'data': 1,
                    'change_type': "some_string",
                }`

In your TSX, make sure to pass in undefined like so. The example on the website was fine without explicitly saying that, but my editor complained about some error. <Tooltip content={<CustomTooltip active={undefined} payload={undefined} label={undefined}/>} />

For CustomToolTip, this was tricky for me to understand. The payload has to have index of 0. Then call dot operator as there's a payload class there to access your custom properties like time, data, and change_type

    const CustomTooltip = ({ active, payload, label }) => {
    if (active && payload && payload.length) {
      return (
        <div className="custom-tooltip">
          <p className="label">{`${label} : ${payload[0].payload.time}`}</p>
          <p className="label">{`${label} : ${payload[0].payload.data}`}</p>
          <p className="label">{`${payload[0].payload.change_type}`}</p>
          <p className="desc">Anything you want can be displayed here.</p>
        </div>
      );
    }
  
    return null;
  };

Then it should pop up in correctly without any issues on hover.

const CustomTooltip = ({
  active,
  payload,
  label,
}: {
  active: boolean;
  label: string;
  payload: {
    payload: {
      value: number
    }
  }[];
}) => {
  if (active) {
    return ( <
      div className = "custom-tooltip" >
      <
      p className = "label" > {
        `${label} : ${payload[0].value}`
      } < /p> <
      p className = "desc" > Anything you want can be displayed here. < /p> <
      /div>
    );
  }

  return null;
};

return ( <
  ComposedChart data = {
    data
  } >
  ...
  <
  Tooltip content = { < CustomTooltip active = {
      false
    }
    payload = {
      []
    }
    label = "" / >
  }
  /> <
  /ComposedChart>
);

It usually works for me,but other way could be:

const CustomTooltip = ({ active, payload, label }: any) => {
Related