Why Your React Projects Need TypeScript

Arian Garshi
3 min readMay 25, 2023

--

TypeScript introduces discipline to React applications primarily through static typing, which permits developers to designate specific types to props, state variables, and function return values, effectively preventing type-related bugs. Additionally, it provides compile-time error detection, offering the ability to catch mistakes before the application is run, a considerable improvement over JavaScript’s runtime error detection.

Static Typing in React components

TypeScript was introduced to address some of the shortcomings of JavaScript. By adding static typing to the language, TypeScript makes codebases more predictable and maintainable, reducing the potential for errors that can occur in a dynamically-typed language like JavaScript. If you are familiar with Java development, this concept should be very familiar. In Java, whenever you declare a new variable, you prefix it with what type it is, such as string, int, float, etc.

TypeScript, especially in React projects, adopts a more layered process. Unlike Java’s approach of prefixing variables directly with their types, TypeScript typically requires us to define interfaces to manage types, which may introduce an additional layer of complexity. Here is an example that demonstrates how we define the type of various props that we expect to get in a component:

interface UserProfileProps {
name: string;
age: number;
isPremiumUser: boolean;
location: {
city: string;
country: string;
};
hobbies: string[];
registrationDate: Date;
}

const UserProfile: React.FC<UserProfileProps> = ({ name, age, isPremiumUser, location, hobbies, registrationDate }) => {
return (
<div>
<h2>{name}</h2>
<p>Age: {age}</p>
<p>Premium User: {isPremiumUser ? 'Yes' : 'No'}</p>
<p>Location: {location.city}, {location.country}</p>
<p>Hobbies: {hobbies.join(", ")}</p>
<p>Registration Date: {registrationDate.toISOString()}</p>
</div>
);
}

export default UserProfile;

As you can see, the interface object provides all expected types for the inserted props. What's very useful about Typescript in this regard is that if you insert a prop with a type that does not match what is declared in the interface, your IDE will throw an error before the code has compiled and loaded on a browser. In practice, this makes it much faster to detect and correct errors.

Another thing that may seem unfamiliar is the FC in React.FC<UserProfileProps>. The FC stands for “Function Component”. It’s a common pattern used to enforce type safety in components when using TypeScript with React.

Static Typing in JavaScript functions

In addition to creating interfaces for React components, you may also introduce Typing to simple functions. Let’s look at an example of a typical JavaScript function:

function area(width, height) {
return width * height;
}

This code may work correctly in many cases, but there’s nothing to prevent us from accidentally passing a string or an undefined value, leading to unexpected results.

With TypeScript, we can explicitly define the types for the function arguments within the prop definition, making the code more predictable and less error-prone:

function area(width: number, height: number): number {
return width * height;
}

By defining types, TypeScript forces us to write code that adheres to specific contracts, reducing the likelihood of runtime errors and making the codebase more maintainable.

Additional advantages of Typescript

Better Tooling and Autocomplete: TypeScript’s type system enables IDEs to provide enhanced autocompletion and refactoring capabilities. This makes understanding a large codebase's structure and data flow easier.

Advanced Types and Utility Types: TypeScript comes with various advanced types and utility types that allow for more precise type definitions and complex type manipulations. This makes it possible to create powerful, type-safe abstractions that are not achievable with JavaScript alone. Examples of such types include mapped types, conditional types, and utility types like “Partial”, “Readonly”, and “Pick”.

Gradual Typing: TypeScript offers a gradual typing system. This means that you can introduce Typescript to any Javascript project without changing the code at all. All Javascript code is validTypescript. This makes it very easy to start defining types in minor parts of the application, to begin with, and then expand the type declarations from there.

Conclusion

Although TypeScript may appear cluttered and cumbersome at first, my experience has taught me that the initially perceived complexity is a worthwhile tradeoff for the inevitable reduction in debugging time. TypeScript’s robust error-checking has caught numerous minor errors that would have taken me ages to correct 2 weeks after having written the code when it finally gets caught. I recommend any web developer using any front-end framework to give it a try

--

--

Arian Garshi
Arian Garshi

Written by Arian Garshi

Software engineer & UX-designer

No responses yet