3
votes

I use this ResizeObserver hook in my project with typescript


const useResizeObserver = () => {
  const [entry, setEntry] = useState<ResizeObserverEntry>();
  const [node, setNode] = useState<Element | null>(null);
  const observer = useRef<ResizeObserver | null>(null);

  const disconnect = useCallback(() => {
    const { current } = observer;
    if (current) {
      current.disconnect();
    }
  }, []);

  const observe = useCallback(() => {
    observer.current = new ResizeObserver(([entry1]) => setEntry(entry1));
    if (node) {
      observer.current.observe(node);
    }
  }, [node]);

  useLayoutEffect(() => {
    observe();
    return () => disconnect();
  }, [disconnect, observe]);

  return [setNode, entry];
};
const [node, entry] = useResizeObserver();
<div ref={node}>content</div>

When i use this hook in my component, I get this error

Type 'Dispatch<SetStateAction<Element | null>> | ResizeObserverEntry | undefined' is not assignable to type 'string | ((instance: HTMLTableHeaderCellElement | null) => void) | RefObject | null | undefined'. Type 'ResizeObserverEntry' is not assignable to type 'string | ((instance: HTMLTableHeaderCellElement | null) => void) | RefObject | null | undefined'. Property 'current' is missing in type 'ResizeObserverEntry' but required in type 'RefObject'.

Help fixed

2
i dont know why but this hook works in js project and doesnt work with typescriptuser14036415

2 Answers

1
votes

You are returning setNode as the first element in the return array and try to use it as a TableHeader ref.

setNode can't be used as a ref, see here on how refs are used

1
votes

I figured out that the issue came from typescript infer as union types as we mix an array [setNode, entry]. So in order to fix this issue, you simply set that as fixed return array as below:

return [setNode, entry] as const;

Note: This const assertions is only featured from v3.4 https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions