Home > OS >  How to solve Type 'HTMLCanvasElement' has no call signatures.ts(2349) for React?
How to solve Type 'HTMLCanvasElement' has no call signatures.ts(2349) for React?

Time:11-18

I have TS errors in the code I am using for the react-canvas-confetti package. I keep on getting the following error when I am trying to define types for my function which you will see below.

(property) React.MutableRefObject<HTMLCanvasElement | null>.current: HTMLCanvasElement This expression is not callable. Type 'HTMLCanvasElement' has no call signatures.ts(2349)

const refAnimationInstance = useRef<HTMLCanvasElement | null>(null)
  
  const getInstance = useCallback((instance: any) => {
    refAnimationInstance.current = instance
  }, [])

  const makeShot = useCallback((particleRatio: number, opts: any) => {
    refAnimationInstance.current &&
      refAnimationInstance.current({
        ...opts,
        particleCount: Math.floor(200 * particleRatio),
      })
  }, [])

I cannot figure out how to define this so that refAnimationInstance does not throw an error here for .current:

refAnimationInstance.current({
        ...opts,
        particleCount: Math.floor(200 * particleRatio),
      })

You can see the working example of the confetti in this link here: https://codesandbox.io/s/realistic-fn-react-canvas-confetti-forked-sixvv1?file=/src/App.js:904-975

CodePudding user response:

It's pretty annoying that this library doesn't export their types, but you can still get it with this long convoluted usage of built-in types:

import { type IProps } from "react-canvas-confetti";

type CreateConfetti = NonNullable<Parameters<NonNullable<IProps["refConfetti"]>>[0]>;

Then use the type where you need it:

const refAnimationInstance = useRef<CreateConfetti | null>(null)
  
const getInstance = useCallback((instance: CreateConfetti) => {
    refAnimationInstance.current = instance
}, []);

Also, you can use optional chaining to avoid having to use && short-circuiting:

refAnimationInstance.current?.({
    ...opts,
    particleCount: Math.floor(200 * particleRatio),
})
  • Related