Igor Shmukler
Igor Shmukler

Reputation: 2246

Typescript and useRef hook causing type error

I made a custom Checkbox component to handle events differently, code below:

const DoubleClickCheckbox = ({ filter, handleDoubleClick, handleSingleClick }: DCCheckboxProps) => {
  const delay = 400;
  const timer = useRef(null);

  const classes = useStyles();
  const flags = useFlags();

  useEffect(() => {
    return () => {
      timer.current && clearTimeout(timer.current);
    };
  }, []);

  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  // @ts-ignore
  const onClick = (e) => {
    if (flags.csRequireFilters) {
      e.stopPropagation();
      handleSingleClick(filter);
      return;
    }

    switch (e.detail) {
      case 1:
        // eslint-disable-next-line @typescript-eslint/ban-ts-comment
        // @ts-ignore
        timer.current = setTimeout(() => {
          handleSingleClick(filter);
        }, delay);
        break;
      case 2:
        // eslint-disable-next-line @typescript-eslint/ban-ts-comment
        // @ts-ignore
        clearTimeout(timer.current);
        handleDoubleClick(filter);
        break;
      default:
        // eslint-disable-next-line @typescript-eslint/ban-ts-comment
        // @ts-ignore
        clearTimeout(timer.current);
        return;
    }
  };

  return (
    <div className={classes.filter} onClick={onClick} onKeyDown={() => {}} role="button" tabIndex={0}>
      <Checkbox
        label={filter.label}
        className={classes.checkbox_custom}
        checked={filter.selected}
        checkedIcon={filter.mandatory ? <Icons.CheckboxDoubleClick /> : <Icons.CheckboxSingleClick />}
      />
    </div>
  );
};

I would like to dump my eslint-disable-next-line @typescript-eslint/ban-ts-comment and ts-ignore.

If I rewrite my code it reads as below, I get a typescript error:

  case 1:
    timer.current = setTimeout(() => {
      handleSingleClick(filter);
    }, delay);
    break;

The error is: Type 'Timeout' is not assignable to type 'null'. I have tried various other tricks, for example: const timer = useRef<React.MutableRefObject<ReturnType<typeof setTimeout>>>(null);.

It did not help either.

Please advise

Upvotes: 0

Views: 1813

Answers (2)

CD..
CD..

Reputation: 74166

Seems like you'r ref can be null or be a number (ReturnType<typeof setTimeout> is number):

const timer = React.useRef<number | null>(null)

Upvotes: 1

chromaloop
chromaloop

Reputation: 222

I think the problem is the useRef(null) implicitly sets it's type as null. You should define it as const timer = useRef<null | () => void>(null)

Upvotes: 0

Related Questions