Introduction
Building projects is always a great way to learn and upskill yourself as a developer. While building a project with Front End Mentor using React and TypeScript, I encountered a TypeScript problem in handling a change event which I want to share how I was able to solve.
Prerequisites
- Basic understanding of React & TypeScript
In React, when you want to keep track of changes made on an input element, you have to make that input element a controlled input by passing a state to the value prop and handle the updating of that state in a method. Here's an example
import { useState } from "react";
function App() {
const [fields, setFields] = useState({
name: "",
email: "",
});
function updateFields(event) {
setFields((prevFields) => {
return { ...prevFields, [event.target.name]: event.target.value };
});
}
return (
<form>
<input
type="text"
name="name"
value={fields.name}
onChange={(e) => updateFields(e)}
/>
<input
type="email"
name="email"
value={fields.email}
onChange={(e) => updateFields(e)}
/>
</form>
);
}
export default App;
Anytime we type inside any input field, the state updates and the update is immediately reflected in the input box. This works fine, but here is the same function written in TypeScript
You will notice a red error line on the event
parameter, TypeScript is saying event has an implicit type of any because it doesn't know the specific kind of event we are running. This might be surprising to you because If you look at the JSX Markup, you would expect TypeScript to know we are calling the change event from an input element, but TypeScript doesn't, why?
TypeScript does not look at the JSX Markup of your component, it only looks at your method definitions
This means TypeScript doesn't care about your JSX structure, it only looks at your method definition to know what to do, so it's your responsibility to provide TypeScript with all the necessary information it needs. Since TypeScript doesn't look at our JSX, it needs to know the kind of event we are listening for which is a change event, let's indicate that in our code.
Now the error is gone, anytime you want to specify an event type, you write the event name using PascalCase style. We now have another issue in our code, TypeScript doesn't know what the name
and value
properties are, why is that?, TypeScript is aware we are calling a change event but it doesn't know which element is calling that change event. At first, this might look stressful, with JavaScript, I don't have to do all this explicit declarations, but understand that the whole point of using TypeScript is to explictly define everything you do in other to make your code scale better, and less prone to errors, so we have to define the type of element that fires off the change event
<HTMLInputElement>
tells TypeScript the ChangeEvent is fired from an input element. You now see the errors are gone because TypeScript has more information about what event.target is, so it knows the name
and value
properties comes from an input element.
As a quick disclaimer, updateFields() will still run even though all these errors we solved are there, but it's only going to work in development. By the time you want to build your project for production, it won't compile.
Conclusion
That's it!, this was how I was able to solve the issues I had with TypeScript while building this web app in React. The same idea works for other types of events as well, you indicate what type of event you are running and tell TypeScript the HTML element that runs the event so that as you write certain properties or methods the element has, it is aware of them. Here's the live url of the project as well as the Github repo if you want to check them out. I am also on X and Linkedin if you want to connect with me. I am open for freelance work too, here's my portfolio.
Top comments (0)