lydal
lydal

Reputation: 940

Parameter 'e' implicitly has an 'any' type React TypeScript

I'm trying to implement this in a React TypeScript File:

export class MainInfo extends Component<IProps>{
  continue = e => {
    e.preventDefault();
    this.props.nextStep();
  };

  render() {
    const { values1, handleChange } = this.props
    return (
      <div>
        <Formik
          validateOnChange={true}
          validationSchema={validationSchema}
          initialValues={{ Title: '', ActivationDate: '', ExpirationDate: '', DirectManager: '', HRBP: '' }}
          onSubmit={(data) => {
            console.log(data)
          }}

But I receive a Parameter 'e' implicitly has an 'any' type React TypeScript error. How should I fix this?

Edit: I have these in another file that Im using them here as props

nextStep = () => {
    const { step } = this.state;
    this.setState({
      step: step + 1
    });
  };

  // Go back to prev step
  prevStep = () => {
    const { step } = this.state;
    this.setState({
      step: step - 1
    });
  };

  // Handle fields change
  handleChange = input => e => {
    this.setState({ [input]: e.target.value });
  };

Upvotes: 18

Views: 68944

Answers (7)

Syed Shuja Shah
Syed Shuja Shah

Reputation: 32

In your code you just need to set the type of event to FormEvent and import it from the react.

import { FormEvent } from "react";

    const handleSubmit = (e: FormEvent) => {
    e.preventDefault();
    console.log("submitted");
  };

Upvotes: 1

Dermo909
Dermo909

Reputation: 178

Saw the same problem myself when trying to add an event handler for the onChange event.

function handleChange(event) {
    var _userDetails = userDetails;
    _userDetails[event.target.name] = event.target.value;
    setUserDetails({ ..._userDetails });
};

event.target.name was showing the error that event implicitly had an 'any' type.

Adding a type to the event did'nt work and then noticed I had named my file with a .tsx extension and not.jsx

Changing the type to jsx solved the issue for me.

Upvotes: 0

AliN11
AliN11

Reputation: 2553

If you want to handle a form submission using onSubmit handler, give React.FormEvent<HTMLFormElement> type to e:

function MyComponent(props) {
  const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
  }

  return (
      <form onSubmit={handleSubmit}>
        { props.children }
      </form>
    )
}

Upvotes: 4

Daniel
Daniel

Reputation: 15413

It is interesting to note that you will not see this error if you are writing inline event handlers, but then why do you see it in this context?

The reason you are seeing that error message is because of the type inference system in TypeScript and how it works.

TypeScript is always trying to figure out the different types of values flowing around your application and that's what the type inference system does.

Let me demonstrate with a screenshot. In the screenshot below I have moused over onChange and you will notice that TypeScript is 100% aware of what that onChange prop really is, it understands it's a prop, it understands I am required to provide some kind of callback function to it. It says that if I decided to provide that function to onChange, it will have a first argument called event and its type will be React.ChangeEvent<HTMLInputElement>:

enter image description here

If I mouse over e inline, notice I get the exact same type:

enter image description here

However, the type inference system is not applied if I define the function ahead of time. Even if I define the function ahead of time and pass it down into the onChange prop, type inference will not be applied.

Type inference is only defined inside the JSX when we define the callback function directly inline.

So how do you fix this? How do we define onChange in my example ahead of time and still annotate the type of my event object?

Well, I can mouse over onChange as you saw in the above screenshot and highlight and copy the type of event which is React.ChangeEvent<HTMLInputElement> and put a colon after event and paste that type in.

In my example it would be:

const EventComponent: React.FC = () => {
  const onChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    console.log(event);
  };

   return (
     <div>
       <input onChange={onChange} />
     </div>
   );
};

Which means, to solve your problem, it would look like so:

export class MainInfo extends Component<IProps>{
  continue = (event: React.ChangeEvent<HTMLInputElement>) => {
    event.preventDefault();
    this.props.nextStep();
  };

Notice the event type says ChangeEvent? Just be aware that there are other events inside of React code such as hover or drag that you might want to annotate as well. Just something to be aware of.

Upvotes: 7

brietsparks
brietsparks

Reputation: 5016

When writing TypeScript you should refer to the source code or docs of the library to know what its types are

For example, in Formik's types.tsx, we see

handleChange(e: React.ChangeEvent<any>): void;

We can also look in React's types to see:

interface ChangeEvent<T = Element> extends SyntheticEvent<T>

So, something like

handleChange = input => (e: React.ChangeEvent<HTMLInputElement>) => {
  this.setState({ [input]: e.target.value });
};

...might work for you.

Also if your IDE supports TypeScript that will help.

Upvotes: 17

matpol
matpol

Reputation: 3074

In this case e is an Event of some kind. If you don't know what Type something is 'any' is the default e.g.

handleChange = input => (e:any) => {
    this.setState({ [input]: e.target.value });
  };

So in the short term use any. If you want to know exactly what type it is it likely an Input Event and you might find this Typescript input onchange event.target.value useful

Upvotes: -1

bruh
bruh

Reputation: 2305

You have to give e a type. For example:

continue = (e: React.FormEvent<HTMLInputElement>) => {
  e.preventDefault()
}

Typescript will scream at you if you don't assign types to variables and function arguments.

Upvotes: 5

Related Questions