Overloads don't match on useRef

775 Views Asked by At

Overloads wont match

import React, { useEffect, useState, useRef } from 'react'


function Button() {

  const [ctr, setCtr] = useState(0)
  let interval = useRef<NodeJS.Timeout | null>(null)

  useEffect(() => {
    interval.current = setInterval(() => {
      setCtr(prev => prev + 1)
    },1000)
    return () => {
      clearInterval(interval.current)
    }
  }, [])
  
 
  return (
    <>
      <span> Count : {ctr} </span>
      <button onClick={ () => clearInterval(interval.current) }> Clear </button>
    </>
  )
}

export default Button

Error:

No overload matches this call.
  Overload 1 of 2, '(intervalId: Timeout): void', gave the following error.
    Argument of type 'Timeout | null' is not assignable to parameter of type 'Timeout'.
      Type 'null' is not assignable to type 'Timeout'.
  Overload 2 of 2, '(handle?: number | undefined): void', gave the following error.
    Argument of type 'Timeout | null' is not assignable to parameter of type 'number | undefined'.
      Type 'null' is not assignable to type 'number | undefined'.ts(2769)

Image:

enter image description here

2

There are 2 best solutions below

0
On

You need to exclude null from type of interval.current

<button onClick={ () => clearInterval(interval.current as Timeout) }> Clear </button>
0
On

I forgot that setInterval is a window object. The problem here is that TS thinks this is a NodeJS construct while it's just a window function. Using the as keyword isn't good practice and should be avoided in most cases. The whole point of typescript is so that it's strong-typed and the usage of as deviates from that.

function Button() {

  const [ctr, setCtr] = useState(0)
  const interval = useRef(0);
  useEffect(() => {
    interval.current = window.setInterval(() => {
      setCtr(prev=>prev+1)
    }, 1000);

    return () => {
      window.clearInterval(interval.current);
    };
  }, []);
  
 
  return (
    <>
      <span> Count : {ctr} </span>
      <button onClick={ () => window.clearInterval(interval.current) }> Clear </button>
    </>
  )
}