'Testing a custom react hook written in typescript

I have a custom hook useForm written in TS and it works just fine. Testing it with @testing-library/react-hooks. The tests pass. But typescript is complaining in a one specific place - see below:

Here is the custom hooks:

import { useState } from 'react';

export function useForm<T>(initialValues: T) {
  const [values, setValues] = useState(initialValues);

  return {
    values: values,
    handleChange: (e: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => {
      setValues({
        ...values,
        [e.target.name]: e.target.value,
      });
    },
    reset: () => setValues(initialValues),
  };
}

Here is the test:

import { renderHook, act } from '@testing-library/react-hooks';

import { useForm } from './useForm';

test('should render useForm hook', () => {
  const { result } = renderHook(() =>
    useForm({
      text: 'Note One',
    }),
  );

  expect(result.current).toBeDefined();
  expect(result.current.values.text).toBe('Note One');

  act(() => {
    result.current.handleChange({
      target: { //complains here - Type '{ name: string; value: string; }' is not assignable to type 'EventTarget & (HTMLTextAreaElement | HTMLInputElement)'.
        name: 'text',
        value: 'Note Two',
      },
    });
  });

  expect(result.current.values.text).toBe('Note Two');

  act(() => {
    result.current.reset();
  });
  expect(result.current.values.text).toBe('Note One');
});

Here is a working code sandbox: https://codesandbox.io/s/flamboyant-curie-6i5moy?file=/src/useForm.test.tsx



Solution 1:[1]

You can simply cast it:

 act(() => {
   result.current.handleChange({
     target: {
       name: 'text',
       value: 'Note Two',
     },
   }) as React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>;
 });

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 SakoBu