DEV Community

Igor Filchev
Igor Filchev

Posted on

Adding typescript to the existing react project

This note will help you understand how to add typescript to an existing Create React App project and start writing new files in the typescript. I use npm as the package manager, but it will not be a problem for you to use yarn or some other way.

If you do not use Redux, do only steps numbered as 1, 2 and 7 only.

Main steps

1) Let’s install required packages via terminal[1]

npm i --save typescript @types/node @types/react 
npm i --save @types/react-dom @types/jest
npm install --save-dev @tsconfig/node16
npm i @typescript-eslint/parser
Enter fullscreen mode Exit fullscreen mode

2) Create tsconfig.json file manually or with terminal command and fill it with my example of the file

tsc --init
Enter fullscreen mode Exit fullscreen mode
{
 "$schema": "https://json.schemastore.org/tsconfig",
 "display": "Node 16",
 "extends": "@tsconfig/node16/tsconfig.json",
 "compilerOptions": {
   "target": "ES2022",
   "lib": [
     "dom",
     "dom.iterable",
     "ES2022"
   ],
   "allowJs": true,
   "skipLibCheck": true,
   "esModuleInterop": true,
   "allowSyntheticDefaultImports": true,
   "strict": true,
   "forceConsistentCasingInFileNames": true,
   "noFallthroughCasesInSwitch": true,
   "module": "es2022",
   "moduleResolution": "node",
   "resolveJsonModule": true,
   "isolatedModules": true,
   "noEmit": true,
   "jsx": "react-jsx",
   "typeRoots": [
     "src/@types"
   ]
 },
 "include": [
   "src"
 ]
}
Enter fullscreen mode Exit fullscreen mode

$schema, display and extends do not set anything to the tsconfig file. They only lead to the online list of options with values, which can be present in the tsconfig.json. In other words, you will have to add configuration by looking at the scheme[2][3].

My IDE changes module from the es2022 to esnext. Do not worry, if you will see this in the notification panel of your IDE.

typeRoots contain a path to the file with the default useSelector app state (explanation you can find later). Erase typeRoots from the file, if you do not use Redux.

3) Skip this step, if you do not use Redux.

It is time to change react-redux index filename extension from .js to .ts (your file can have another name). After that replace

export default combineReducers({
   ...yourReducers
});
Enter fullscreen mode Exit fullscreen mode

with

export const reducers = combineReducers({
   ...yourReducers
})

export type AppState = ReturnType<typeof reducers>;
Enter fullscreen mode Exit fullscreen mode

Explanation of the AppState purpose will be later

4) This section is needed for the developers, which utilize Redux.

Modify file store.js (your implementation file can have another name). You will have to replace

import reducers from './reducers';
Enter fullscreen mode Exit fullscreen mode

with

import { reducers } from './reducers/index.ts';
Enter fullscreen mode Exit fullscreen mode

5) Please, ignore this step, if you do not use redux.

And current step requires creation of the file react-app-env.d.ts (src/react-app-env.d.ts)[4]

/// <reference types="react-scripts" />
Enter fullscreen mode Exit fullscreen mode

6) Well, this file is not needed for the not-redux users

Add file under path src/@types/react-redux.d.ts with next code

import 'react-redux';

import { AppState } from '../reducers';

declare module 'react-redux' {
   interface DefaultRootState extends AppState {}
}
Enter fullscreen mode Exit fullscreen mode

Despite AppState being not used anywhere else, it allows not to import reducers app state in the useSelector method every time and the method always know the it’s argument type return value[5].

7) Well, modify ESlint file as the last step:

  • Change parser
"parser": "@typescript-eslint/parser",
Enter fullscreen mode Exit fullscreen mode
  • Change parser options
"parserOptions": {
   "ecmaVersion": "latest",
   ...rest code
}
Enter fullscreen mode Exit fullscreen mode
  • Update env
"env": {
   "es2021": true,
   ...rest code
}
Enter fullscreen mode Exit fullscreen mode
  • Modify rules for disabling warnings or errors for unused code (by your choice only), removing mistake about typescript file extensions (code will work without this rule, but you will see unpleasant message) and remove warning about lack of default props
"rules": {
   "no-use-before-define": "off",
   "react/jsx-filename-extension": [2, { "extensions": [".js", ".jsx", ".ts", ".tsx"] }],
   "react/require-default-props": "off"
}
Enter fullscreen mode Exit fullscreen mode

Conclusion

I have to warn you, that file import with .ts and .tsx extensions is obligatory now (you can ignore it only in the created by create-react-app application). As a disadvantage, live reloading can be broken and you will have to reload the page manually every time.

Sources

[1] Adding TypeScript
[2] What is a tsconfig.json
[3] tsconfig.json base configuration
[4] What is the react-app-env.d.ts in a react typescript project for
[5] TS2339: Property 'tsReducer' does not exist on type 'DefaultRootState'

Top comments (0)