title: 'Illegal invocation' using input setCustomValidity and TS
body: <p>I'm pretty much new to Typescript world and am converting one of the first React applications.</p>
  <p>Here I'm trying to set custom messages on input validation by using <code>event.target.setCustomValidity</code> but I'm getting the 'Illegal invocation' error when the setCustomValidity function gets triggered.</p>
  <p><a href="https://codesandbox.io/s/awesome-pike-snw1q?file=/src/Input.tsx" rel="nofollow noreferrer">Here</a> there is the sandbox; To trigger the error it's just required to update the first input.</p>
  <p>Debugging the error, I'd think the issue stands on the declared type of <code>event.target</code> set <code>as HTMLInputElement</code>, or on the declared type of <code>event</code> set as a <code>React.SyntheticEvent</code>; Perhaps I'm using the wrong types for the event which doesn't always have a setCustomValidity function?</p>
  <p>To premise the code used on the sandbox works perfectly fine without Typescript</p>
  <p>Any suggestion is highly appreciated, thank you in advance for your help!</p>
  <p><strong>Components code</strong></p>
  <p>App.tsx:</p>
  <pre><code>import React, { useState } from &quot;react&quot;;
  import Input from &quot;./Input&quot;;
  import &quot;./styles.css&quot;;
  
  export default function App() {
    // Check if value entered is a valid email. Ref: http://emailregex.com/
    const emailPattern = /^(([^&lt;&gt;()[\]\\.,;:\s@&quot;]+(\.[^&lt;&gt;()[\]\\.,;:\s@&quot;]+)*)|(&quot;.+&quot;))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))/;
  
    const initialForm = {
      username: &quot;&quot;,
      password: &quot;&quot;
    };
    const [form, setForm] = useState(initialForm);
  
    // Listen to form inputs and updates form state respectively
    const handleChange = (event: React.SyntheticEvent) =&gt; {
      const {
        name,
        value,
        type,
        setCustomValidity
      } = event.target as HTMLInputElement;
      setForm({ ...form, [name]: value });
  
      if (type === &quot;email&quot; &amp;&amp; !emailPattern.test(value)) {
        setCustomValidity(&quot;Please select a valid email address.&quot;);
      } else {
        setCustomValidity(&quot;&quot;);
      }
    };
  
    return (
      &lt;div className=&quot;App&quot;&gt;
        &lt;Input
          id=&quot;username&quot;
          type=&quot;string&quot;
          name=&quot;username&quot;
          label=&quot;username&quot;
          value={form[&quot;username&quot;]}
          onChange={handleChange}
          required={true}
        /&gt;
        &lt;Input
          id=&quot;password&quot;
          type=&quot;password&quot;
          name=&quot;password&quot;
          label=&quot;password&quot;
          value={form[&quot;password&quot;]}
          onChange={handleChange}
          required={true}
        /&gt;
      &lt;/div&gt;
    );
  }
  </code></pre>
  <p>Input.tsx:</p>
  <pre><code>import React from &quot;react&quot;;
  
  type PropsType = {
    id: string;
    type: string;
    name: string;
    value: string;
    label: string;
    onChange: (event: React.SyntheticEvent) =&gt; void;
    required: boolean;
  };
  
  /**
   * Reusable standard Input component.
   * @param {Object} props - Props passed from parent component containing input attributes.
   * @return - Controlled input element.
   */
  const Input: React.FC&lt;PropsType&gt; = ({
    id,
    type,
    label,
    onChange,
    required,
    ...rest
  }: PropsType) =&gt; (
    &lt;div className=&quot;input&quot;&gt;
      &lt;input
        id={id}
        type={type}
        placeholder=&quot;&quot;
        {...rest}
        onChange={(event) =&gt; onChange(event)}
        minLength={type === &quot;password&quot; ? 8 : undefined}
      /&gt;
      &lt;label htmlFor={id}&gt;
        {label}
        {required &amp;&amp; &quot; *&quot;}
      &lt;/label&gt;
    &lt;/div&gt;
  );
  
  export default Input;
  </code></pre>