LoginSignup
2
3

More than 3 years have passed since last update.

既存ReactプロジェクトにTypeScriptを導入した話

Last updated at Posted at 2019-12-01

アソビュー Advent Calendar 2019の2日目。

フロントエンドエンジニアの指田です。
今回はアソビューの既存ReactプロジェクトにTypeScriptを導入した内容についてお話します。

はじめに

Babelでコンパイルしている既存ReactプロジェクトにTypeScriptを導入した話です。
本記事ではTypeScript等の説明は致しません。

導入

  • 既存のビルド構成は変更しない。(@babel/preset-typescriptを利用。ts-loaderは使用しない)
  • 導入直後はコード変更もしない。
  • 完全にTypeScriptにするまでJavaScriptとTypeScriptは混在する。

インストール

JavaScript Standard Styleを利用しているため、Typescriptのconfigも追加してます。

# TypeScript
yarn add -D typescript 

# Babel
yarn add -D @babel/preset-typescript

# ESLint
yarn add -D @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint-config-standard-with-typescript

設定

最初の設定は悩みました。
設定を厳しくしすぎると、開発が進まなくなるので必要そうな設定のみで導入しました。

TypeScript

初期はallowJs(JavaScriptもトランスパイルに含めるかどうか)は外して導入してます。

{
  "compilerOptions": {
    "skipLibCheck": true,
    "isolatedModules": true,
    "esModuleInterop": true,
    "strict": true,
    "noImplicitAny": false,
    "noImplicitThis": true,
    "strictNullChecks": true,
    "noImplicitReturns": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
  },
}

ESLint

overridesを使用してJavaScriptもTypeScriptも同じ様にlintが効くようにしてます。

{
  "env": {
    "browser": true,
    "jest": true
  },
  "extends": [
    "standard",
    "standard-with-typescript",
    "standard-jsx",
    "plugin:react/recommended",
    "plugin:css-modules/recommended"
  ],
  "plugins": [
    "react-hooks",
    "css-modules"
  ],
  "rules": {
    "react/prop-types": 0,
    "standard/computed-property-even-spacing": "off",
    "react-hooks/rules-of-hooks": "error"
  },
  "parser": "babel-eslint",
  "settings": {
    "react": {
      "version": "detect"
    },
    "node": {
      "tryExtensions": [".ts", ".tsx", ".js"]
    },
  },
  "overrides": [
    {
      "files": ["*.ts", "*.tsx"],
      "plugins": [
        "@typescript-eslint",
        "react-hooks",
        "css-modules"
      ],
      "parser": "@typescript-eslint/parser",
      "parserOptions": {
        "sourceType": "module",
        "project": "./tsconfig.json"
      },
      "rules": {
        "@typescript-eslint/explicit-member-accessibility": "off",
        "@typescript-eslint/explicit-function-return-type": "off",
        "@typescript-eslint/promise-function-async": [
          "error",
          {
            "allowedPromiseNames": [],
            "checkArrowFunctions": false,
            "checkFunctionDeclarations": true,
            "checkFunctionExpressions": false,
            "checkMethodDeclarations": false
          }
        ]
      }
    }
  ]
}

prettier

{
  "overrides": [
    {
      "files": ["*.ts", "*.tsx"],
      "options": {
        "parser": "typescript"
      }
    }
  ]
}

npm script

JavaScriptも含めたチェックできるtscコマンドも用意しました。

{
  "scripts": {
    "ts-compile-check": "tsc -p tsconfig.json --noEmit",
    "ts-compile-check-in-js": "tsc -p tsconfig.json --noEmit --allowJs",
  },
}

型について

導入直後はanyまたは未指定で進めました。

型を定義していない状態は意味があるのか?とは思いますが、
引数の誤り、不要なPropsがなくなるのでコードがきれいになるメリットがあります。

まとめ

  • 既存コードがある場合、初期の導入範囲はなるべく小さくすることをおすすめします。
  • Babelを使用しているのであれば、@babel/preset-typescriptを利用する方が早めに導入できると思います。
  • ESLint等の設定はoverridesを利用し、混在しても問題ないようにするのがいいと思います。

最後に

アソビューではTypeScriptを導入したプロジェクトはまだ少数なので全てのReactプロジェクトへ導入を検討して行きたいです。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3