3

The goal is to make a reusable hook that effects on DOM.

Example Code:

import { useEffect, useRef } from 'react';

function useFocus() {
  const domRef = useRef<HTMLElement | null>(null);

  useEffect(() => {
    domRef.current?.focus()
  }, []);

  return {
    domRef
  };
}

const App = () => {
  const { domRef } = useFocus();

  return (
    <div>
      <input type='text' ref={domRef} />
    </div>
  );
};

export default App;

Error occur:

TypeScript error in /Users/yoki/Code/Demos/use-ref-demo/src/App.tsx(20,26):
Type 'MutableRefObject<HTMLElement | null>' is not assignable to type 'LegacyRef<HTMLInputElement> | undefined'.
  Type 'MutableRefObject<HTMLElement | null>' is not assignable to type 'RefObject<HTMLInputElement>'.
    Types of property 'current' are incompatible.
      Type 'HTMLElement | null' is not assignable to type 'HTMLInputElement | null'.
        Type 'HTMLElement' is missing the following properties from type 'HTMLInputElement': accept, align, alt, autocomplete, and 49 more.  TS2322

    18 |   return (
    19 |     <div>
  > 20 |       <input type='text' ref={domRef} />
       |                          ^
    21 |     </div>
    22 |   );
    23 | }; 

Question: How can I give the correct type for useRef<...>() ?

The right thinking is to give the type that any type which exntends from HTMLElememnt, instead of any or assertion, please help.

The dom is not limited to input, it can be div or input or span etc, so HTMLInputElement type is not good for this case.

1
  • Isn't it an object type? Commented Mar 22, 2021 at 5:32

1 Answer 1

0

Take a closer look at the error message: Type 'HTMLElement | null' is not assignable to type 'HTMLInputElement | null'.. The correct type, according to the message is HTMLInputElement | null. Also, it make sense to change useFocus a bit:

useEffect(() => {
    domRef.current?.focus()
  }, [domRef]);
Sign up to request clarification or add additional context in comments.

6 Comments

Thank you, but we aren't supposed to know the type of dom, it could be any dom.
In that case, put React.useRef<any>(null)
I also required not to use any : ( Because any can solve anything or nothing
oh, I see, another option is to use union - '|' and define the type like 'HTMLInputElement | HTMLElement | null'
@DenisMalykhin Still, we don't specify the dom type, it could be HTMLInputElement or HTMLDivElement or HTMLSVGElement ....
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.