Search code examples
javascriptreactjstypescriptfocus

How can I get React.js TypeScript to accept 'parentElement' on 'event.target' with a onKeyDown event?


I have a special accessible element built with React TypeScript and I am trying to define keys to navigate it and to be able to focus within the table element. It is built specially for screen readers... However I just can not seem to get the types down.

I can not get rid of the following error:

Property 'parentElement' does not exist on type 'EventTarget'.ts(2339)

here is the function I am trying to declare:

 const keyDownHandler = (event: React.KeyboardEvent) => {
    event.preventDefault();

    if (event.key === "ArrowLeft") {
      (event.target.parentElement.nextElementSibling.firstElementChild as HTMLButtonElement).focus();
    }
    if (event.key === "ArrowUp") {
      console.log("keys.up");
    }
    if (event.key === "ArrowRight") {
      console.log("keys.right");
    }
    if (event.key === "ArrowDown") {
      console.log("keys.down");
    }
  };

I also tried to force type with the "!" as

event.target.parentElement!.nextElementSibling.firstElementChild.focus();

(These<td><button></button></td> are placed next to each other in <tr/>)

and here is how I render:

 <table role="presentation" onKeyDown={keyDownHandler}>
        <DaysHeading />
        <DatesOfMonth
          year={dateObject.year}
          month={dateObject.month}
          datesOfMonth={dateObject.dates}
          setClickedDate={setClickedDate}
        />
      </table>

What am I missing?


Solution

  • This is because TypeScript is seeing event.target as an EventTarget type instead of a HTMLElement type. You could solve this by casting event.target to a HTMLElement type like this.

    const keyDownHandler = (event: React.KeyboardEvent) => {
            event.preventDefault();
        
            if (event.key === "ArrowLeft") {
              const eventTarget: HTMLElement = event.target;
              (eventTarget.parentElement.nextElementSibling.firstElementChild as HTMLButtonElement).focus();
            }
            if (event.key === "ArrowUp") {
              console.log("keys.up");
            }
            if (event.key === "ArrowRight") {
              console.log("keys.right");
            }
            if (event.key === "ArrowDown") {
              console.log("keys.down");
            }
          };