When you learn TypeScript, you’re definitely taking a leap to find an existing JavaScript project and revamping it.

Start with a psychological massage: Migrating existing projects will be a gradual process, not a one-shot process.

There are three main strategies for project migration:

  • Coexistence strategy
  • easing
  • Strict policy

Take the React project as an example. The first two steps of the three strategies are the same:

The installation

Install the typescript and React declaration files

$ npm i typescript @types/react @types/react-dom
Copy the code

Initialize the tsconfig. Json

$ tsc --init
Copy the code
  • tsconfig.json
    {
      "jsx": "react"
    }
    Copy the code

Coexistence strategy

The so-called coexistence strategy: the original JS code is not modified, the new code is written in TS.

Babel – loader? Ts – loader?

If your build tool relies heavily on Babel, you can use babel-Loader for language conversion and TSC for type checking. Otherwise, you can use a lighter TS-Loader.

Since most React projects currently use Babel, let’s first look at how we chose Babel

babel-loader

  • Install @ Babel/preset – typescript

    $ npm i -D @babel/preset-typescript
    Copy the code
  • Modify the Babel configuration

    {
      "presets": [
        "@babel/env"."@babel/preset-react",
    +    "@babel/preset-typescript"]."plugins": [
        "@babel/proposal-class-properties"."@babel/proposal-object-rest-spread"]}Copy the code
  • Modify the webpack. Base. Config. Js

    module.exports = {
      // ...
      resolve: {
        extensions: [".js".".jsx".".ts".".tsx"],},module: {
        rules: [{test: /\.(j|t)sx? $/,
            use: [
              {
                loader: "babel-loader"],},exclude: /node_modules/,},],},};Copy the code
    • Adding type Checking

      • tsconfig.json

        {
          "compilerOptions": {
            "noEmit": true}}Copy the code
      • Package. json: Add type checking scripts

        {
          // ...
          "scripts": {
            // ...
            "type-check": "tsc --watch"}}Copy the code

ts-loader

The TS-Loader process is simpler

  • Install the ts – loader

    npm i ts-loader -D
    Copy the code
  • Modify the webpack. Base. Config. Js

    module.exports = {
      // ...
      resolve: {
        extensions: [".js".".jsx".".ts".".tsx"],},module: {
        rules: [
          // ...
          {
            test: /\.tsx? $/,
            use: [
              {
                loader: "ts-loader"],},exclude: /node_modules/,},],},};Copy the code

Js and JSX should not be spared

  • tsconfig.json

    ** All subdirectories. Subdirectories that contain subdirectories. * is just a level 1 subdirectory

    {
      "include": ["./src/**/*"]."compilerOptions": {
        // ...
        "allowJs": true."checkJs": true}}Copy the code

Type checking errors do not affect the build.

There are two ways to handle errors without modifying the JS code:

  • @ts-nocheck

    // @ts-nocheck
    export function add(x, y) {
      return x + y;
    }
    Copy the code
  • JSDoc

    This approach also does type checking when writing code

    / * * *@param {number} x
     * @param {number} y* /
    export function add(x, y) {
      return x + y;
    }
    Copy the code

easing

Loose policy: rename all JS/JSX to TS/TSX. And on the basis of not modifying the code, use the most lax inspection rules, ignore the rest of the error, make the project run.

rename

Let’s use ShellJS to do the renaming, so let’s install ShellJS;

The node command looks for JS files by default, so we’ll also need to install TS-Node to help us find TS files.

$ npm i -D shelljs @types/shelljs ts-node
Copy the code

Create renamejs.ts in the root directory:

import * as shelljs from "shelljs";

shelljs
  .find("src") // Find the SRC folder and return an array
  .filter((file) = > file.match(/\.jsx? $/)) // Filter out js/ JSX files
  .forEach((file) = > {
    let newName = file.replace(/\.j(sx?) $/.".t$1");
    shelljs.mv(file, newName); / / renamed
  });
Copy the code

The mv command of shell means moving, which is actually accomplished by cp and rm.

Configure the rename script (package.json) :

{
  "scripts": {
    // ...
    "rename-js": "ts-node renameJS.ts"}}Copy the code

Modify the two entry files for WebPack and Package: JSX -> TSX

Modify the type check rule

  • tsconfig.json

    {
      "compilerOptions": {
        // "allowJs": true,
        // "checkJs": true,
        "strict": false
        /* Additional Checks */
        / /... All closed (false)}}Copy the code

This relaxed check rule will reduce most errors; But the new TS files also lose strict type checking.

So, it’s more of a transition strategy.

Strict policy

Strict policies enable the strictest type checking rules to handle all errors.

You also need to rename the file first, see loose policy/Rename.

Type check rule (tsconfig.json), type check related configurations are enabled (true) :

{
  "compilerOptions": {
    /* Strict Type-Checking Options */
    "strict": true
    // ...

    /* Additional Checks */
    // ...}}Copy the code