DEV Community

Cover image for Reasons to Use Typescript with React - Get the Benefits of Static Typing and IntelliSense
Luis Cadillo
Luis Cadillo

Posted on • Edited on

Reasons to Use Typescript with React - Get the Benefits of Static Typing and IntelliSense

What is Typescript?

TypeScript is a strict super-set of JavaScript that extends the language with types. This allows for static type checking, which can catch errors before runtime. TypeScript is compiled into JavaScript, and the resulting code can target any flavor of JavaScript. TypeScript also allows for the creation of custom types and interfaces, which can be applied to plain JavaScript objects. This provides improved autocomplete in IDEs and can help prevent errors.

How do I start writing TypeScript code?

  1. Before you start writing your TypeScript code, you can create a tsconfig.json file. This file allows you to configure the TypeScript compiler and customize how it transpiles your code into Javascript.

  2. You write your TypeScript code in a .ts file. This code can include optional type annotations and other TypeScript-specific features.

  3. You run the tsc command on your .ts file, which stands for TypeScript compiler.

  4. The compiler transpile your TypeScript code into vanilla JavaScript that is compatible with the specified JavaScript flavor or runtime.

  5. The compiled JavaScript code is saved to a .js file with the same name as the original .ts file.

  6. You can then run the .js file in a browser or other JavaScript runtime environment to execute your code.

So in summary, the TypeScript compiler takes your TypeScript code and converts it into regular JavaScript that can be run in any JavaScript environment. This allows you to use the additional features of TypeScript, such as static type checking, without worrying about compatibility.

Is it always necessary to follow this process to compile TypeScript code into JavaScript?

Luckily is not. When using a web framework like Next.js, the TypeScript compilation step is usually handled automatically for you behind the scenes. This means that you can write your code in TypeScript and the framework will take care of transpiling it to JavaScript and running it in the appropriate environment.

Reasons to use Typescript with React

Wouldn't it be great if you could improve your developer experience, reduce the need for unit testing and enhance refactoring capabilities with React? Well, you can just add TypeScript to the mix! TypeScript adds static type checking and improved autocomplete to your code, making it easier to catch errors before runtime and helping you be more productive. It’s a great way of ensuring the maintainability and scalability of your React application.

Are you excited to explore the advantages of using TypeScript with React? Let's take a look at why TypeScript can be a great addition to your React projects!

IntelliSense

In-line documentation

The Language Server Protocol (LSP) is an open-source protocol developed by Microsoft that allows editors and IDEs to communicate with language servers. These language servers enable features such as IntelliSense and in-line documentation. When using TypeScript, the TypeScript compiler sends information about the project and its code to the tsserver (the language server for TypeScript). This can help you write code more quickly and easily by providing helpful auto-completion and documentation.

Use state IDE autocompletion example

Many libraries provide pre-built support for TypeScript, allowing us to take advantage of helpful auto-completion and in-line documentation right away.

Tailwind IDE autocompletion example

With TypeScript, you can type the props of a React component, providing it with more detailed and helpful documentation.

Easier debugging

TypeScript is strongly typed, which means that the compiler will catch type errors before the app is run. This can help you to identify bugs faster because the compiler will show right away where an error has occurred.

Take a look at this example:

Debugging form input types example

TypeScript is showing us exactly where the error occurred. By rendering the name field conditionally, onSubmit's input parameter could receive either an undefined or string value, which is not what we initially intended and could lead to undesired values being passed to our backend if we don’t fix it.

As you can see, TypeScript's strict type-checking can be a great help when it comes to debugging and quickly identifying errors that could otherwise go unnoticed until later in the development process.

Enhanced refactoring experience

Due to its strongly typed nature, TypeScript can greatly improve your refactoring experience by alerting you of changes in your code, such as variable names, types, and the presence of undefined values. This allows you to make changes more confidently, knowing that your code will still be working after you refactor it.

Refactoring useState example

Reduces the need for unit testing

Using Typescript with React can reduce the need for unit testing because of its static type-checking capabilities. Type-checking enables developers to catch bugs before they run the code, which can save time and effort in manual (sometimes pointless) testing.

For example, many JavaScript developers write unit tests to ensure their code is not receiving invalid inputs such as null or undefined or an object instead of an array. When it comes to React, using Typescript can save us time by preventing us from having to double up on bug fixes. Through its static type-checking capabilities, Typescript can detect errors on the fly and alert us if a certain type of input is not valid. This helps reduce the need for unit testing by ensuring that our input types are always correct, allowing us to focus more on testing for behavior rather than for types.

Improves maintainability and scalability

By taking advantage of TypeScript static type system we can write code that is both scalable and maintainable.

Scalability

Using TypeScript with React can help make your projects more scalable by being able to create typed components which can be reused by the whole team. With the in-line documentation of what a component can receive as props and what it is supposed to return, extending your app can become faster and smoother. This can reduce the time needed to get new developers on board and make them productive.

Maintainability

Your React projects can become easier to maintain because now you can confidently make changes throughout your codebase knowing that if your changes break something, TypeScript will immediately let you know, making refactoring easier. Your codebase can also become easier to understand and navigate thanks to auto-completion and go-to-definition features provided by the TypeScript language server which can also greatly improve your ability to refactor the code and thus improve maintainability.

Increases productivity in the long run

Imagine you've been working on an important feature for some time now. You've put a lot of effort into it. You've also made sure you haven't passed any invalid values to the key functions that make the app work. But then you open the app and it crashes. You then spend hours debugging, trying to figure out the cause. When you finally do figure it out, you realize that you had passed an object to a function that was expecting an array.

But with TypeScript, those errors become easily detectable and you can avoid the pain and suffering of those debugging sessions. There's a sort of safety net guaranteeing that our code won't crash if we forget to check a certain data type, because it won’t even compile instead it will point you through IntelliSense to the exact function where things went wrong.

This helps us work on large codebases without having to maintain complex mental models of what types of data each function can take, and gives us the freedom to focus on the actual code. Ultimately, this increases the overall productivity of a team, as developers no longer need to worry about every detail and can focus on actually writing code instead.

What steps should you take to start using TypeScript with React?

Configs

To start using TypeScript with React, you will first need to install the TypeScript compiler and the type definitions for React. You can do this using the following steps:

  • Open a terminal or command prompt and run the following command to install the TypeScript compiler globally on your system:
 npm install -g typescript
Enter fullscreen mode Exit fullscreen mode
  • Next, navigate to the root directory of your React project and run the following command to install the type definitions for React:
npm install --save-dev @types/react @types/react-dom
Enter fullscreen mode Exit fullscreen mode
  • Next, init TypeScript in your React project with:
tsc —init —jsx react
Enter fullscreen mode Exit fullscreen mode
  • --init: Initializes a TypeScript project and creates a tsconfig.json file.

  • --jsx react: Specify what JSX code is generated. one of: preserve, react, react-native, react-jsx, react-jsxdev. default: undefined

  • You can now start writing TypeScript files in your project by running the following command, where filename.tsx is the name of the file you want to create:

touch fileame.tsx
Enter fullscreen mode Exit fullscreen mode
  • Compile
tsc --outDir
Enter fullscreen mode Exit fullscreen mode
  • tsc: Compiles the current project (tsconfig.json in the working directory.)

  • --outDir: Specify an output folder for all emitted files.

Alternatively, you can use a tool like create-react-app to scaffold a new React project with TypeScript support built-in. This will automatically set up a TypeScript-enabled project for you, with the TypeScript compiler and the React type definitions already installed. You can then start writing TypeScript code in your React app right away.

Next.js:

npx create-next-app@latest --ts
Enter fullscreen mode Exit fullscreen mode

React TypeScript Cheatsheet basic setup page can help you find other ways to start using TypeScript in a React project.

Basic typing

You can gradually start implementing TypeScript in an already existing React project. The defaults that tsc —init or React frameworks give you are good enough to get you started, once you’ve explored the TypeScript-React workflow you will probably want to play with the tsconfig.json file for stronger typing.

But for now here are some of the must-know React types:

Prop types

// TypeScript types for props
type Props = {
  name: string,
  age: number,
  favoriteFoods: string[]
}

// The component itself
const MyComponent = (props: Props) => {
  // Destructuring the props object for easier access
  const { name, age, favoriteFoods } = props;

  // Use the props in the component
  return (
    <div>
      <p>Name: {name}</p>
      <p>Age: {age}</p>
      <p>Favorite Foods: {favoriteFoods.join(', ')}</p>
    </div>
  );
}

// Example usage of the component
<MyComponent
  name="John Doe"
  age={32}
  favoriteFoods={["pizza", "burgers", "tacos"]}
/>
Enter fullscreen mode Exit fullscreen mode

In this example, we have defined a component called MyComponent that takes in three props: name, age, and favoriteFoods. We have also used TypeScript's type system to define the types of these props: name is a string, age is a number, and favoriteFoods is an array of strings. This allows TypeScript to catch any errors that may occur if the component is passed props with the wrong types.

React.useState
Type inference works very well for simple values:

const [state, setState] = useState(false);
// `state` is inferred to be a boolean
// `setState` only takes booleans
Enter fullscreen mode Exit fullscreen mode

You can also explicitly provide types for your state values like this:

const [user, setUser] = useState<User | null>(null);

// later...
setUser(newUser);
Enter fullscreen mode Exit fullscreen mode

This is especially useful when your state will hold the result of for example an API call and naturally the initial data shape is different from the result this API call will return.

Sometimes you might need to pass down stateValue and stateSetter, for those scenarios you will have to correctly type the stateSetter:

type MyComponentProps = {
  car: Car,
  setAnime: React.Dispatch<React.SetStateAction<Car>>
}

const MyComponent = ({car, setCar}: MyComponentProps) => {
  // ...
}
Enter fullscreen mode Exit fullscreen mode

React.Dispatch<React.SetStateAction<Car>> is a custom type provided by the React library. React provides many of these custom types for stuff like typing event objects, React components, etc.

To get the most out of React with TypeScript, take a look at the React TypeScript Cheatsheet for more information about the many advantages TypeScript provides for React developers.

Conclusion

If you’re working with React, then using TypeScript can be a great way to ensure that the code you write is always reliable and secure. TypeScript’s static type-checking capabilities allow developers to catch errors early and avoid costly debugging sessions, and its IntelliSense can provide valuable insight into how the code works. With TypeScript, you can also maintain a large codebase without needing to manually check and debug types, making it far easier to scale applications reliably. Ultimately, using TypeScript with React helps ensure that applications are stable and maintainable, reducing development time and improving productivity in the long run.

References

Top comments (0)