recharts: Layer: TypeScript error with latest `@types/react` version

  • I have searched the issues of this repository and believe that this is not a duplicate.

Reproduction link

https://stackblitz.com/edit/vitejs-vite-raiemq?file=package.json,src%2FApp.tsx

Steps to reproduce

When building recharts without skipLibCheck: true a TypeScript error is thrown with v18.2.74 of @types/react. I believe the root cause is how TypeScript infers and represents types for forwardRef, but unfortunately I wasn’t able to fix it myself.

  1. Go to StackBlitz
  2. run tsc in terminal
  3. See the following error:
node_modules/recharts/types/container/Layer.d.ts:7:108 - error TS2344: Type '"string" | "filter" | "values" | "fill" | "stroke" | "max" | "type" | "accumulate" | "offset" | "key" | "id" | "media" | "origin" | "height" | "width" | "end" | "name" | "min" | "alignmentBaseline" | ... 450 more ... | "onPointerLeaveCapture"' does not satisfy the constraint '"string" | "filter" | "values" | "fill" | "stroke" | "max" | "type" | "accumulate" | "offset" | "key" | "id" | "media" | "origin" | "height" | "width" | "end" | "name" | "min" | "alignmentBaseline" | ... 457 more ... | "onTransitionEndCapture"'.
  Type '"onPointerEnterCapture"' is not assignable to type '"string" | "filter" | "values" | "fill" | "stroke" | "max" | "type" | "accumulate" | "offset" | "key" | "id" | "media" | "origin" | "height" | "width" | "end" | "name" | "min" | "alignmentBaseline" | ... 457 more ... | "onTransitionEndCapture"'. Did you mean '"onPointerOverCapture"'?

7 export declare const Layer: React.ForwardRefExoticComponent<Pick<React.SVGProps<SVGGElement> & LayerProps, "string" | "ideographic" | "alphabetic" | "hanging" ...[shortened for readability]> & React.RefAttributes<unknown>>;

What is expected?

Types for React v18 should be supported.

What is actually happening?

Error is thrown.

Environment Info
Recharts v2.12.3
React ^18.2.0
System macOS 14.3.1 (23D60)
Browser -

"@types/react": "18.2.74"

About this issue

  • Original URL
  • State: closed
  • Created 3 months ago
  • Reactions: 2
  • Comments: 19 (10 by maintainers)

Commits related to this issue

Most upvoted comments

Looks like the xyzCapture events were removed in react types in 18.x because they don’t do anything.

Relevant react issue https://github.com/facebook/react/issues/17883

Our generated declaration files include these removed events which breaks you with skipLibCheck: true.

We’ll upgrade react types in 3.x and this shouldn’t be an issue anymore, but probably won’t do it in 2.x for risk of breaking something else.

Thanks!

CC: @PavelVanecek

Lmk if this looks okay https://github.com/recharts/recharts/pull/4413 (fixing some related types while I’m at it, not sure why Pie was an HTMLElement…)

Yeah that makes sense @ckifer, thanks for taking a look at this. I’ve had a quick look and here’s my thinking. The SVGProps interface…

interface SVGProps<T> extends SVGAttributes<T>, ClassAttributes<T>

… is SVGAttributes anyway with ClassAttributes, which is

interface ClassAttributes<T> extends Attributes {
  ref?: LegacyRef<T> | undefined;
}

interface Attributes {
  key?: Key | null | undefined;
}

… so the ref and key which aren’t part of SVGAttributes need to be added, and are added implicitly from createElement. and you can see that Attributes and ClassAttributes are added anyway, which is why key and ref are always available in your IDE even when you don’t specify it.

const MyComponent = () => null;
const Foo = () => <MyComponent key="IT_WORKS" />

const MyComponentForwarded = forwardRef(() => null);
const Bar = () => <MyComponentForwarded key="IT_WORKS" ref={useRef()} />;

Thanks @ckifer!

I did a bit more digging and came to the following result, maybe it helps:

Typically, type discrepancies shouldn’t be an issue, as long as only the imported types are used, allowing consumers to define the version of, e.g. @types/react on their end. In this case, it appears that the forwardRef types are transformed to leverage the SVGProps' keys for the Pick utility type. Consequently, these keys are bundled in with the @types/react version used in this project. If a type from SVGProps (or any interface it extends) is removed, the described error is thrown.