Search code examples
typescriptjestjsreact-testing-library

How to avoid TypeScript error when using closest() in React Testing Library?


In my unit test, I am trying to select the following div so that I can click on it.

<div>
  <h1>Avocado Toast</h1>
  <p>Avocado toast served on country bread, served with a side of veggies</p>
</div>

Based on this stackoverflow answer I tried to use getByText() in combination with closest():

const avocadoToast = screen.getByText('Avocado Toast').closest('div');
userEvent.click(avocadoToast);

However Typescript complains on the second line that avocadoToast could be null (because closest() could return a null):

error TS2345: Argument of type 'HTMLDivElement | null' is not assignable to parameter of type 'Element'.
      Type 'null' is not assignable to type 'Element'.

I have worked around the problem by adding a non-null assertion operator to this line:

userEvent.click(avocadoToast!);

However I feel that I am not structuring the test correctly. Is there a better way?


Solution

  • After a lot of research and guidance from Kent C. Dodds, I decided on the following solution because of its simplicity:

    const avocadoToast = screen.getByText('Avocado Toast').closest('div');
    
    // use an invariant to verify that avocadoToast is not null
    // this now satisfies TypeScript in the last line
    if (avocadoToast === null) {
      // fail the test right here so that rest of the test is not complicated
      throw new Error("Couldn't find Avocado Toast");
    }
    
    userEvent.click(avocadoToast);
    

    Note that the correct way to fail a test in Jest is to throw an error (see this stackoverflow answer)

    A more elaborate way to fix the solution would be to make the original HTML (intended to be a card) more accessible by using the guidelines here.