0

On the verge of giving up on Typescript, everything just seems to be made harder. Trying to follow a simple react-idle-timer video and a few minutes in already facing Typescript compilation problems. Searching online for guides on how to use useRef with typescript says to just put the type you expect in <> when making the useRef call. On paper that sounds good to me and should work, yet here I am facing issues yet again with TS.

import { useRef } from 'react';
import IdleTimer from 'react-idle-timer';

function IdleTimerContainer() {
    const idleTimerRef = useRef<IdleTimer | null>(null);
    function onIdle() {
        console.log('user is idle');
    }
    return (
        <div>
            <IdleTimer timeout={5 * 1000} onIdle={onIdle} ref={idleTimerRef} />
        </div>
    );
}
export default IdleTimerContainer;

TS2769: No overload matches this call.   Overload 1 of 2, '(props: IdleTimerClassProps | Readonly): IdleTimer', gave the following error.     Type 'MutableRefObject<IdleTimer | null>' is not assignable to type '(LegacyRef & ((ref: IdleTimer) => any)) | undefined'.       Type 'MutableRefObject<IdleTimer | null>' is not assignable to type 'RefObject & ((ref: IdleTimer) => any)'.         Type 'MutableRefObject<IdleTimer | null>' is not assignable to type '(ref: IdleTimer) => any'.           Type 'MutableRefObject<IdleTimer | null>' provides no match for the signature '(ref: IdleTimer): any'.   Overload 2 of 2, '(props: IdleTimerClassProps, context: any): IdleTimer', gave the following error.     Type 'MutableRefObject<IdleTimer | null>' is not assignable to type '(LegacyRef & ((ref: IdleTimer) => any)) | undefined'. index.d.ts(143, 9): The expected type comes from property 'ref' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes & Readonly & Readonly<...>' index.d.ts(143, 9): The expected type comes from property 'ref' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes & Readonly & Readonly<...>'

TrollBearPig
  • 496
  • 1
  • 7
  • 17

1 Answers1

4

It's not your fault! Your code is fine, it's the react-idle-timer package itself that's doing it wrong.

interface IdleTimerClassProps extends IdleTimerProps {
    /**
     * React reference to the IdleTimer Component instance.
     */
    ref?: (ref: IdleTimer) => any
}

This section of the source code makes it so that you can only use a callback style ref and not a ref object.

Your ref object should be just a TS issue, not a JS issue, so you can circumvent the problems with the package by using as any.

<IdleTimer timeout={5 * 1000} onIdle={onIdle} ref={idleTimerRef as any} />

You'll still have proper TypeScript types on the idleTimerRef variable.

Linda Paiste
  • 38,446
  • 6
  • 64
  • 102