TS Error Type 'false' has no call signatures TS (2349)

Viewed 854

I am getting a TS error on the SetIsActive and the error is 'This expression is not callable. Not all constituents of type 'boolean | Dispatch<SetStateAction>' are callable. Type 'false' has no call signatures.TS(2349)' Not really sure how to fix the error, Thanks in advance

the DetectOutsideClick Component has an error on 'e' and 'contains' with the error "Property 'contains' does not exist on type 'never'.ts(2339)"

import ArrowDown from '../../../assets/images/event-landing-pre-event/triangle-down.svg';
import { DetectOutsideClick } from './detect-outside-click';

export const DropDownButton = () => {
  const dropdownRef = useRef(null);
  const [isActive, setIsActive] = DetectOutsideClick(dropdownRef, false);
  const handleClick = () => setIsActive(!isActive);

  return (
    <div className="">
      <div className="">
        <button onClick={handleClick} className="flex items">
          <span className="text-blue-800 font-semibold mx-3">My registration</span>
          <img className="mr-1" src={ArrowDown} alt="User avatar" />
        </button>
        <nav
          ref={dropdownRef}
          className={`absolute top-8  w-80 opacity-0
          ${isActive ? 'opacity-100 visible' : ''}`}
        >
          <ul className="">
            <li className="block">
              <a href="#">Order Confirmation</a>
            </li>
          </ul>
        </nav>
      </div>
    </div>
  );
};

export default DropDownButton;





import { useState, useEffect, MutableRefObject } from 'react';

export const DetectOutsideClick = (el: MutableRefObject<null>, initialState: boolean) => {
  const [isActive, setIsActive] = useState(initialState);

  useEffect(() => {
    const onClick = (e) => {
      if (el.current !== null && !el.current.contains(e.target)) {
        setIsActive(!isActive);
      }
    };

    if (isActive) {
      window.addEventListener('click', onClick);
    }

    return () => {
      window.removeEventListener('click', onClick);
    };
  }, [isActive, el]);

  return [isActive, setIsActive];
};
1 Answers

Just use return [isActive, setIsActive] as const; and you'll be good to go.

Like our buddy @tokland told on his answer, TS has no way to tell a tuple from an array and resuming it, as const does that for you.

You can read more and learn with other examples on the oficial TS documentation here

Related