
React with TypeScript: Best Practices
React has emerged as the preferred library for creating contemporary online applications, and TypeScript improves React development by offering better developer experience and static type verification. Maintainability, improved tools support, and fewer runtime problems are guaranteed when React and TypeScript are combined. In order to maximize efficiency, maintainability, and scalability, this blogpost examines the best approaches for integrating TypeScript with React.
Setting Up React with TypeScript
To start a new, React project with TypeScript, use the following command:
npx create-react-app my-app –template typescript
Alternatively, if adding TypeScript to an existing project, install the necessary dependencies:
npm install –save-dev typescript @types/react @types/react-dom
Best Practices
We have compiled this helpful list of the most frequent use cases for React with TypeScript after researching the most often asked questions. In this manner, you can utilize this page as a guide for your own work.
Setting up
Configuration is one of the most crucial yet least enjoyable aspects of development. How can we get everything set up as quickly as possible to maximize productivity and efficiency? We’ll talk about project setup, which includes:
- json
- ESLint
- Prettier
- VS Code extensions and settings.
Project Setup
Using create-react-app with the TypeScript template is the fastest way to launch a React/TypeScript application. You can run to accomplish this:
npx create-react-app my-app –template typescript
This will provide you the essentials to begin writing TypeScript React. A few significant distinctions are:
- the .tsx file extension
- the tsconfig.json
- the react-app-env.d.ts
For “TypeScript JSX,” the tsx is used. The TypeScript configuration file, tsconfig.json, has a few default settings specified. The types of react-scripts are referenced in the react-app-env.d.ts, which also aids in enabling SVG imports.
tsconfig.json
We are fortunate that tsconfig.json is generated for us by the most recent React/TypeScript template. To begin, though, they add the bare minimum. We advise you to change yours to resemble the one below. We’ve included remarks to further clarify each option’s purpose:
{
"compilerOptions": {
"target": "es5", // Specify ECMAScript target version
"lib": [
"dom",
"dom.iterable",
"esnext"
], // List of library files to be included in the compilation
"allowJs": true, // Allow JavaScript files to be compiled
"skipLibCheck": true, // Skip type checking of all declaration files
"esModuleInterop": true, // Disables namespace imports (import * as fs from "fs") and enables CJS/AMD/UMD style imports (import fs from "fs")
"allowSyntheticDefaultImports": true, // Allow default imports from modules with no default export
"strict": true, // Enable all strict type checking options
"forceConsistentCasingInFileNames": true, // Disallow inconsistently-cased references to the same file.
"module": "esnext", // Specify module code generation
"moduleResolution": "node", // Resolve modules using Node.js style
"isolatedModules": true, // Unconditionally emit imports for unresolved files
"resolveJsonModule": true, // Include modules imported with .json extension
"noEmit": true, // Do not emit output (meaning do not compile code, only perform type checking)
"jsx": "react", // Support JSX in .tsx files
"sourceMap": true, // Generate corrresponding .map file
"declaration": true, // Generate corresponding .d.ts file
"noUnusedLocals": true, // Report errors on unused locals
"noUnusedParameters": true, // Report errors on unused parameters
"incremental": true, // Enable incremental compilation by reading/writing information from prior compilations to a file on disk
"noFallthroughCasesInSwitch": true // Report errors for fallthrough cases in switch statement
},
"include": [
"src/**/*" // *** The files TypeScript should type check ***
],
"exclude": ["node_modules", "build"] // *** The files to not type check ***
}
The Compiler Options documents in the Official TypeScript Handbook provide the explanations, while the react-typescript-cheatsheet community provides the extra suggestions. If you would like to know more about different options and what they do, this is a great resource.
ESLint/Prettier
It is advised that you set up ESLint and Prettier to make sure your code complies with project or team guidelines and maintains a consistent style. Use these steps to set it up so they will play well.
Set up the necessary development dependencies:
yarn add eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-react --dev
Add the following to a.eslintrc.js file created at the root:
module.exports = {
parser: '@typescript-eslint/parser', // Specifies the ESLint parser
extends: [
'plugin:react/recommended', // Uses the recommended rules from @eslint-plugin-react
'plugin:@typescript-eslint/recommended', // Uses the recommended rules from @typescript-eslint/eslint-plugin
],
parserOptions: {
ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features
sourceType: 'module', // Allows for the use of imports
ecmaFeatures: {
jsx: true, // Allows for the parsing of JSX
},
},
rules: {
// Place to specify ESLint rules. Can be used to overwrite rules specified from the extended configs
// e.g. "@typescript-eslint/explicit-function-return-type": "off",
},
settings: {
react: {
version: 'detect', // Tells eslint-plugin-react to automatically detect the version of React to use
},
},
};
Add Prettier dependencies:
yarn add prettier eslint-config-prettier eslint-plugin-prettier --dev
Create a.prettierrc.js file at the root and add the following:
module.exports = {
semi: true,
trailingComma: 'all',
singleQuote: true,
printWidth: 120,
tabWidth: 4,
};
Update the.eslintrc.js file:
module.exports = {
parser: '@typescript-eslint/parser', // Specifies the ESLint parser
extends: [
'plugin:react/recommended', // Uses the recommended rules from @eslint-plugin-react
'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin
+ 'prettier/@typescript-eslint', // Uses eslint-config-prettier to disable ESLint rules from @typescript-eslint/eslint-plugin that would conflict with prettier
+ 'plugin:prettier/recommended', // Enables eslint-plugin-prettier and displays prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array.
],
parserOptions: {
ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features
sourceType: 'module', // Allows for the use of imports
ecmaFeatures: {
jsx: true, // Allows for the parsing of JSX
},
},
rules: {
// Place to specify ESLint rules. Can be used to overwrite rules specified from the extended configs
// e.g. "@typescript-eslint/explicit-function-return-type": "off",
},
settings: {
react: {
version: 'detect', // Tells eslint-plugin-react to automatically detect the version of React to use
},
},
};
VS Code Settings and Extensions
After adding ESLint and Prettier, we will automatically correct and prettify our code upon saving, which will further enhance our DX.
Install the Prettier and ESLint extensions for Visual Studio Code first. ESLint will be able to smoothly interact with your editor as a result.
Next, add the following to your.vscode/settings.json file to alter your Workspace settings:
{
"editor.formatOnSave": true
}
This will allow VS Code to work its magic and fix your code when you save.
Components
Components are one of the fundamental ideas of React. In this context, “standard components” refers to React v16.8 components, which employ hooks rather than classes.
For basic components, there is generally a lot to be concerned about. Let’s examine an illustration:
import React from 'react'
// Written as a function declaration
function Heading(): React.ReactNode {
return <h1>My Website Heading</h1>
}
// Written as a function expression
const OtherHeading: React.FC = () => <h1>My Website Heading</h1>
Take note of the main distinction here. Our function is written as a function declaration in the first example. We use React to annotate the return type. Node since that’s what it gives back. The second example, however, makes use of a function expression. We utilize React to annotate the function type as the second instance returns a function rather than a value or expression. FC stands for “Function Component” in React.
It can be difficult to distinguish between the two. Mostly, it comes down to design preference. Make continuous usage of whichever you decide to utilize for your project.
Advanced Tips
(1) Use tsconfig.json for Strict Typing
Enable strict typing for better error detection:
(2) Avoid Using any
The any type defeats the purpose of TypeScript. Use specific or generic types instead.
(3) Leverage TypeScript with Context API
Properly type your Context values to avoid runtime errors.
Example:
Final words…
Runtime errors are decreased, code maintainability is improved, and the development experience is improved when TypeScript is used with React.
Developers can produce reliable and scalable React apps by adhering to best practices, which include defining strict types, utilizing TypeScript’s features, and enforcing consistency with ESLint and Prettier. Adopting these best practices guarantees improved teamwork and a more efficient development process.