Ошибка useRef Typescript: свойство ‘current’ не существует для типа ‘HTMLElement’

#javascript #reactjs #typescript #visual-studio-code #react-hooks

#javascript #reactjs #typescript #visual-studio-code #реагирующие крючки

Вопрос:

Я создаю Datepicker с помощью React и Typescript, и, похоже, я не могу преодолеть ошибки с useRef .current помощью свойства и ссылки. Я пытаюсь заставить div ссылку, которой я назначаю, закрываться при нажатии на документ за его пределами.

Я просто не могу понять, что я делаю неправильно. Вот мой код:

 function Datepicker({label, placeholder}: DatepickerProps){
  const [open, setOpen] = React.useState(false)
  const [day, setDay] = React.useState(0)
  const [month, setMonth] = React.useState(new Date().getMonth())
  const [year, setYear] = React.useState(new Date().getFullYear())
  const picker = React.useRef(null) as HTMLElement | null

  React.useEffect(() => {
    document.addEventListener("mousedown", toggle)
    return () => {
      document.removeEventListener("mousedown", toggle)
    };
  }, []);

  const toggle = (e: MouseEvent) => {
    if (picker amp;amp; picker.current){
      if (picker.current.contains(e.target) === false){
        setOpen(false)
      }
    }
  }

  //...

  return(
    
    //...

    <div 
      ref={picker}
      className={"datepicker-picker"   (open ? " open" : "")}
    >

      //...

  )
}


  

React.useRef(null) as HTMLElement | null вызывает у меня следующую проблему:

 Conversion of type 'MutableRefObject<null>' to type 'HTMLElement' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
  Type 'MutableRefObject<null>' is missing the following properties from type 'HTMLElement': accessKey, accessKeyLabel, autocapitalize, dir, and 234 more.ts(2352)
  

.current выдает мне следующее:

 Property 'current' does not exist on type 'HTMLElement'.
  

и когда я пытаюсь применить ссылку к div элементу, он говорит следующее:

 Type 'HTMLElement | null' is not assignable to type 'string | ((instance: HTMLDivElement | null) => void) | RefObject<HTMLDivElement> | null | undefined'.
  Type 'HTMLElement' is not assignable to type 'string | ((instance: HTMLDivElement | null) => void) | RefObject<HTMLDivElement> | null | undefined'.
    Type 'HTMLElement' is not assignable to type 'string'.ts(2322)
index.d.ts(143, 9): The expected type comes from property 'ref' which is declared here on type 'DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>'
  

Я использую VSCode в качестве своей IDE, если это вообще поможет.

Ответ №1:

useRef не возвращает значение в ссылке — ввод возвращаемого значения HTMLElement | null является неточным. Вместо этого используйте общий аргумент:

 const picker = React.useRef<HTMLElement>(null);
  

Вам также необходимо изменить toggle , чтобы сужение типа происходило по желанию:

 const toggle = (e: MouseEvent) => {
  const { current } = picker;
  if (current amp;amp; !current.contains(e.target)) {
    setOpen(false);
  }
}
  

Комментарии:

1. Это помогло с первой ошибкой и последней! (Я использовал HTMLDivElement вместо этого) Теперь он выдает мне эту ошибку: Argument of type 'EventTarget | null' is not assignable to parameter of type 'Node | null'. кроме того, мой файл .tsx, могу ли я выполнять утверждения типа в форме useRef<HTMLElement> ?

2. Похоже, вам нужно утверждать, что целью события является узел: e.target as Node . разрешено ли мне выполнять утверждения типа в форме Sure , хотя это не утверждение типа, это параметр типа, которому передается useRef . Такие параметры типа просто прекрасны.

3. ref={picker as React.RefObject<HTMLDivElement>}