简体   繁体   中英

Typescript error in ReactJS tests with React Testing Library

I'm using ReactJS and Material UI and Typescript. I want to test my menu - should show after I click on button with label Location . New menu should contain Location 1 item.

describe('<LocationsMenu />', () => {
    let component: RenderResult;

    beforeEach(() => {
        component = render(<LocationsMenu />);
    });

    it('should show and hide on click on top item trigger', async () => {
        const button = component.getByText('Locations').parentElement;
        await act(async () => {
            fireEvent.click(button);
        });
        expect(component.getByText('Location 1')).toBeDefined();
    });
});

This works - test passes.

Visual Studio Code shows me error in fireEvent.click(button) line: Argument of type 'HTMLElement | null' is not assignable to parameter of type 'Element | Node | Document | Window'. Argument of type 'HTMLElement | null' is not assignable to parameter of type 'Element | Node | Document | Window'. . How can I avoid it? I know I can do type casting like:

fireEvent.click(button as Element);

or

const button = component.getByText('Locations').parentElement as Element;

But maybe there is a better solution.

Typescript can deduce your variable type at any position in the source file, you need to 'cast' the button to HTMLElement instead of HTMLElement | null HTMLElement | null by checking if it's not null

// button may be null
const button = component.getByText('Locations').parentElement;

if (button) {
  // at this point, typescript knows that button cannot be null
  // so it has HTMLElement type in the block
  fireEvent.click(button);
}

Also note that I don't wrap fireEvent.click() inside act() . It's because react-testing-library has already done that for you so it's unnecessary here.

If what you want is brevity and you are absolutely sure the the element exists or the test would failed otherwise, you can ensure typescript by adding a non-null assertion operator like this

// button may be null, but you say it's not
const button = component.getByText('Locations').parentElement!;

fireEvent.click(button);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM